Cloudflare Worker Cache 出现问题 API
Trouble with Cloudflares Worker Cache API
我现在已经花了无数个小时试图让缓存 API 来缓存一个简单的请求。我让它工作了一次,但忘了向缓存键添加一些东西,现在它不再工作了。不用说,cache.put()
没有 return 值来指定请求是否实际被缓存并不能完全帮助我,我只能反复试验。有人可以提示我做错了什么以及实际需要什么吗?我已经阅读了所有文档 3 遍以上,我不知所措......
可能值得注意的是,此 REST 端点将 pragma: no-cache
和其他所有内容 cache-related 设置为 no-cache,但无论如何我都想强行缓存响应,这就是为什么我试图完全 re-write缓存之前的headers,但是还是不行(不匹配或者不存储,没人知道。。。)
async function apiTest(token, url) {
let apiCache = await caches.open("apiResponses");
let request = new Request(
new URL("https://api.mysite.com/api/"+url),
{
headers: {
"Authorization": "Bearer "+token,
}
}
)
// Check if the response is already in the cloudflare cache
let response = await apiCache.match(request);
if (response) {
console.log("Serving from cache");
}
if (!response) {
// if not, ask the origin if the permission is granted
response = await fetch(request);
// cache response in cloudflare cache
response = new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: {
"Cache-Control": "max-age=900",
"Content-Type": response.headers.get("Content-Type"),
}
});
await apiCache.put(request, response.clone());
}
return response;
}
在此先感谢您的帮助,我先在 Cloudflare 社区上提出了同样的问题,但 2 周内没有收到答复
这可能与您使用 caches.default
而不是使用 caches.open("whatever")
打开私有缓存有关。当您使用 caches.default
时,您将共享 fetch()
本身使用的相同缓存。所以当你的worker运行时,你的worker检查缓存,然后fetch()
检查缓存,然后fetch()
稍后写入缓存,然后你的worker也写入相同的缓存条目。由于写操作特别是异步发生的(当响应流通过时),它们很可能重叠并且缓存变得混乱并且将它们全部扔掉。
为避免这种情况,您应该打开一个私有缓存命名空间。所以,替换这一行:
let cache = caches.default;
与:
let cache = await caches.open("whatever");
(这个 await
总是立即完成;它只是因为 Cache API 标准坚持认为这个方法是异步的。)
这样,您将读取和写入一个完全独立于 fetch()
本身 reads/writes.
的缓存条目
caches.default
的用例是当您有意想要对 fetch()
也会使用的缓存条目进行操作时,但我认为您不需要在这里这样做。
编辑:根据下面的对话,我现在怀疑 Authorization
header 的存在导致缓存拒绝存储响应。但是,使用自定义缓存命名空间(如上所述)意味着您可以使用没有 header 的 Request
安全地缓存值,因为您知道缓存的响应只能由Worker 通过缓存 API。听起来这种方法对你的情况有效。
我现在已经花了无数个小时试图让缓存 API 来缓存一个简单的请求。我让它工作了一次,但忘了向缓存键添加一些东西,现在它不再工作了。不用说,cache.put()
没有 return 值来指定请求是否实际被缓存并不能完全帮助我,我只能反复试验。有人可以提示我做错了什么以及实际需要什么吗?我已经阅读了所有文档 3 遍以上,我不知所措......
可能值得注意的是,此 REST 端点将 pragma: no-cache
和其他所有内容 cache-related 设置为 no-cache,但无论如何我都想强行缓存响应,这就是为什么我试图完全 re-write缓存之前的headers,但是还是不行(不匹配或者不存储,没人知道。。。)
async function apiTest(token, url) {
let apiCache = await caches.open("apiResponses");
let request = new Request(
new URL("https://api.mysite.com/api/"+url),
{
headers: {
"Authorization": "Bearer "+token,
}
}
)
// Check if the response is already in the cloudflare cache
let response = await apiCache.match(request);
if (response) {
console.log("Serving from cache");
}
if (!response) {
// if not, ask the origin if the permission is granted
response = await fetch(request);
// cache response in cloudflare cache
response = new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: {
"Cache-Control": "max-age=900",
"Content-Type": response.headers.get("Content-Type"),
}
});
await apiCache.put(request, response.clone());
}
return response;
}
在此先感谢您的帮助,我先在 Cloudflare 社区上提出了同样的问题,但 2 周内没有收到答复
这可能与您使用 caches.default
而不是使用 caches.open("whatever")
打开私有缓存有关。当您使用 caches.default
时,您将共享 fetch()
本身使用的相同缓存。所以当你的worker运行时,你的worker检查缓存,然后fetch()
检查缓存,然后fetch()
稍后写入缓存,然后你的worker也写入相同的缓存条目。由于写操作特别是异步发生的(当响应流通过时),它们很可能重叠并且缓存变得混乱并且将它们全部扔掉。
为避免这种情况,您应该打开一个私有缓存命名空间。所以,替换这一行:
let cache = caches.default;
与:
let cache = await caches.open("whatever");
(这个 await
总是立即完成;它只是因为 Cache API 标准坚持认为这个方法是异步的。)
这样,您将读取和写入一个完全独立于 fetch()
本身 reads/writes.
caches.default
的用例是当您有意想要对 fetch()
也会使用的缓存条目进行操作时,但我认为您不需要在这里这样做。
编辑:根据下面的对话,我现在怀疑 Authorization
header 的存在导致缓存拒绝存储响应。但是,使用自定义缓存命名空间(如上所述)意味着您可以使用没有 header 的 Request
安全地缓存值,因为您知道缓存的响应只能由Worker 通过缓存 API。听起来这种方法对你的情况有效。