Skip to content

Instantly share code, notes, and snippets.

@rajeshg
Created March 14, 2022 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rajeshg/e7dcda1806fc4e0202392cca10231569 to your computer and use it in GitHub Desktop.
Save rajeshg/e7dcda1806fc4e0202392cca10231569 to your computer and use it in GitHub Desktop.
cache images from origin, resize and convert to avif/webp
// 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