Created
March 14, 2022 14:18
-
-
Save rajeshg/e7dcda1806fc4e0202392cca10231569 to your computer and use it in GitHub Desktop.
cache images from origin, resize and convert to avif/webp
This file contains 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
// https://developers.cloudflare.com/images/resizing-with-workers | |
// https://developers.cloudflare.com/workers/examples/cache-api/ | |
addEventListener('fetch', (event) => { | |
if (/image-resizing/.test(event.request.headers.get("via"))) { | |
return fetch(event.request) | |
} | |
event.respondWith(handleRequest(event)) | |
}) | |
async function handleRequest(event) { | |
let request = event.request | |
let url = new URL(request.url) | |
// Construct the cache key from the cache URL | |
const cacheKey = new Request(url.toString(), request); | |
const cache = caches.default; | |
// Check whether the value is already available in the cache | |
// if not, you will need to fetch it from origin, and store it in the cache | |
// for future access | |
let response = await cache.match(cacheKey); | |
if (!response) { | |
console.log( | |
`Response for request url: ${url} is not present in cache. Fetching and caching request.` | |
); | |
// If not in cache, get it from origin | |
const accept = event.request.headers.get("accept"); | |
const isAVIFSupported = /image\/avif/.test(accept); | |
const isWebPSupported = /image\/webp/.test(accept); | |
let options = { cf: { image: {} } } | |
if (url.searchParams.has('fit')) | |
options.cf.image.fit = url.searchParams.get('fit') | |
if (url.searchParams.has('width')) | |
options.cf.image.width = url.searchParams.get('width') | |
if (url.searchParams.has('height')) | |
options.cf.image.height = url.searchParams.get('height') | |
if (url.searchParams.has('quality')) | |
options.cf.image.quality = url.searchParams.get('quality') | |
let format = undefined | |
if (isAVIFSupported) { | |
options.cf.image.format = "avif" | |
format = "avif" | |
} else if (isWebPSupported) { | |
options.cf.image.format = "webp" | |
format = "webp" | |
} | |
const imageURL = url.searchParams.get('image') | |
console.log('imageURL', imageURL) | |
const imageRequest = new Request(imageURL, { | |
headers: request.headers, | |
cf: { | |
image: { format }, | |
cacheEverything: true, | |
cacheKey: cacheKey, | |
cacheTtlByStatus: { '200-299': 3600, '404': 10, '500-599': 0 } | |
}, | |
}) | |
response = await fetch(imageRequest) | |
console.log('response', response) | |
// Store the fetched response as cacheKey | |
// Use waitUntil so you can return the response without blocking on | |
// writing to cache | |
event.waitUntil(cache.put(cacheKey, response.clone())); | |
} else { | |
console.log(`Cache hit for: ${request.url}.`); | |
} | |
return response; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment