Last active
February 24, 2024 02:58
-
-
Save steveyiyo/d7e5ed19ed2a63c9a970d44a5d97db22 to your computer and use it in GitHub Desktop.
Cloudflare Worker 搭配 Backblaze B2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const b2Domain = ''; //你要在Cloudflare上綁定的Backblaze網域 | |
const b2Bucket = ''; //Backblaze B2的存儲桶名稱 | |
const b2UrlPath = `/file/${b2Bucket}/`; | |
addEventListener('fetch', event => { | |
return event.respondWith(fileReq(event)); | |
}); | |
// define the file extensions we wish to add basic access control headers to | |
const corsFileTypes = ['png', 'jpg', 'gif', 'jpeg', 'webp']; | |
// backblaze returns some additional headers that are useful for debugging, but unnecessary in production. We can remove these to save some size | |
const removeHeaders = [ | |
'x-bz-content-sha1', | |
'x-bz-file-id', | |
'x-bz-file-name', | |
'x-bz-info-src_last_modified_millis', | |
'X-Bz-Upload-Timestamp', | |
'Expires' | |
]; | |
const expiration = 31536000; // override browser cache for images - 1 year | |
// define a function we can re-use to fix headers | |
const fixHeaders = function(url, status, headers){ | |
let newHdrs = new Headers(headers); | |
// add basic cors headers for images | |
if(corsFileTypes.includes(url.pathname.split('.').pop())){ | |
newHdrs.set('Access-Control-Allow-Origin', '*'); | |
} | |
// override browser cache for files when 200 | |
if(status === 200){ | |
newHdrs.set('Cache-Control', "public, max-age=" + expiration); | |
}else{ | |
// only cache other things for 5 minutes | |
newHdrs.set('Cache-Control', 'public, max-age=300'); | |
} | |
// set ETag for efficient caching where possible | |
const ETag = newHdrs.get('x-bz-content-sha1') || newHdrs.get('x-bz-info-src_last_modified_millis') || newHdrs.get('x-bz-file-id'); | |
if(ETag){ | |
newHdrs.set('ETag', ETag); | |
} | |
// remove unnecessary headers | |
removeHeaders.forEach(header => { | |
newHdrs.delete(header); | |
}); | |
return newHdrs; | |
}; | |
async function fileReq(event){ | |
const cache = caches.default; // Cloudflare edge caching | |
const url = new URL(event.request.url); | |
if(url.host === b2Domain && !url.pathname.startsWith(b2UrlPath)){ | |
url.pathname = b2UrlPath + url.pathname; | |
} | |
let response = await cache.match(url); // try to find match for this request in the edge cache | |
if(response){ | |
// use cache found on Cloudflare edge. Set X-Worker-Cache header for helpful debug | |
let newHdrs = fixHeaders(url, response.status, response.headers); | |
newHdrs.set('X-Worker-Cache', "true"); | |
return new Response(response.body, { | |
status: response.status, | |
statusText: response.statusText, | |
headers: newHdrs | |
}); | |
} | |
// no cache, fetch image, apply Cloudflare lossless compression | |
response = await fetch(url, {cf: {polish: "lossless"}}); | |
let newHdrs = fixHeaders(url, response.status, response.headers); | |
if(response.status === 200){ | |
response = new Response(response.body, { | |
status: response.status, | |
statusText: response.statusText, | |
headers: newHdrs | |
}); | |
}else{ | |
response = new Response('找不到檔案!', { status: 404 }) | |
} | |
event.waitUntil(cache.put(url, response.clone())); | |
return response; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment