Cloudflres工作缓存API出现问题

我现在已经花费了无数个小时来尝试让缓存API缓存一个简单的请求。我让它在中间工作过一次,但忘了向缓存键中添加一些东西,现在它不再工作了。不用说,cache.put()没有指定请求是否被实际缓存的返回值并不完全有帮助,我只能反复试验。也许有人能给我一个提示,告诉我我做错了什么,实际上需要什么?我现在已经把所有的文件读了三遍以上,我完全不知所措了。…

可能值得注意的是,这个REST终结点设置了pragma: no-cache和其他所有与无缓存相关的缓存,但无论如何我都想强制缓存响应,这就是为什么我试图在缓存之前完全重写标头,但它仍然不起作用(不匹配或不存储,没有人知道…)

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社区上问了同样的问题,但在两周内没有收到答复


解决方案

这可能与您使用caches.default而不是使用caches.open("whatever")打开专用缓存有关。当您使用caches.default时,您共享的缓存与fetch()本身使用的缓存相同。因此,当您的Worker运行时,您的Worker检查缓存,然后fetch()检查缓存,然后fetch()写入缓存,然后您的Worker也写入相同的缓存条目。由于写入操作特别是异步发生的(当响应流过时),它们很可能是重叠的,并且缓存被混淆并将它们全部丢弃。

要避免这种情况,您应该打开私有缓存命名空间。因此,请替换此行:

let cache = caches.default;

使用:

let cache = await caches.open("whatever");

(此await始终立即完成;之所以需要它,只是因为缓存API标准坚持此方法是异步的。)

这样,您正在读取和写入一个与fetch()本身读取/写入的缓存项完全不同的缓存项。

caches.default的用例是您有意操作fetch()也将使用的缓存项,但我认为您不需要在此处执行此操作。


编辑:根据下面的对话,我现在怀疑Authorization头的存在导致缓存拒绝存储响应。但是,使用自定义缓存命名空间(如上所述)意味着您可以使用没有该头的Request来安全地缓存值,因为您知道缓存的响应只能由Worker通过缓存API访问。听起来这种方法在您的案例中奏效了。

相关文章