I am using worker to do my caching task based on device type because the theme I am using doesn't have a separate mobile cache and also Cloudflare doesn't have device type caching at the server's edge, Therefor I used a worker to do this task. With the normal GET request at first, it shows cache status dynamic after a couple of reloads it shows to hit.
There is also a POST method in the worker code so when the POST request is made then it should make also a GET request so the cache for that product is saved. The problem I am facing with the POST method whenever I publish a product the cache is not re-validated and therefore I am getting an old cache. Even if I purge cache it doesn't re-validate cache or show expire cache, It shows to hit.
I know I am not doing it wrong, I would be very thankful if you can help me, below is the code snippet I am using.
Thank you so much.
async function run(event) {
const { request } = event;
const cache = caches.default;
// Read the user agent of the request
const ua = request.headers.get('user-agent');
let uaValue;
if (ua.match(/mobile/i)) {
uaValue = 'mobile';
} else {
uaValue = 'desktop';
}
// Construct a new response object which distinguishes the cache key by device
// type.
const url = new URL(request.url);
url.searchParams.set('ua', uaValue);
const newRequest = new Request(url, request);
let response = await cache.match(newRequest);
if (!response) {
// Use the original request object when fetching the response from the
// server to avoid passing on the query parameters to our backend.
response = await fetch(request);
response = new Response(response.body, response)
response.headers.append("Cache-Control", "max-age=31536000")
// Store the cached response with our extended query parameters.
event.waitUntil(cache.put(newRequest, response.clone()));
}
return response;
}
async function sha256(message) {
// encode as UTF-8
const msgBuffer = new TextEncoder().encode(message)
// hash the message
const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer)
// convert ArrayBuffer to Array
const hashArray = Array.from(new Uint8Array(hashBuffer))
// convert bytes to hex string
const hashHex = hashArray.map(b => ("00" + b.toString(16)).slice(-2)).join("")
return hashHex
}
async function handlePostRequest(event) {
const request = event.request
const body = await request.clone().text()
const hash = await sha256(body)
const cacheUrl = new URL(request.url)
// Store the URL in cache by prepending the body's hash
cacheUrl.pathname = "/posts" + cacheUrl.pathname + hash
// Convert to a GET to be able to cache
const cacheKey = new Request(cacheUrl.toString(), {
headers: request.headers,
method: "GET",
})
const cache = caches.default
// Find the cache key in the cache
let response = await cache.match(cacheKey)
// Otherwise, fetch response to POST request from origin
if (!response) {
response = await fetch(request)
event.waitUntil(cache.put(cacheKey, response.clone()))
}
return response
}
addEventListener("fetch", event => {
try {
const request = event.request
if (request.method.toUpperCase() === "POST")
return event.respondWith(handlePostRequest(event))
return event.respondWith(run(event))
} catch (e) {
return event.respondWith(new Response("Error thrown " + e.message))
}
})
question from:
https://stackoverflow.com/questions/65862227/javascript-caching-api-issues 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…