2

我现在花了无数个小时试图让缓存 API 缓存一个简单的请求。我让它在两者之间工作过一次,但忘记在缓存键中添加一些东西,现在它不再工作了。不用说,cache.put()没有一个返回值来指定请求是否实际被缓存并不能完全帮助我,我只能反复试验。有人可以提示我做错了什么以及实际需要什么吗?我现在已经阅读了所有文档超过 3 遍,我很茫然……</p>

值得注意的是,这个 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 社区上提出了相同的问题,但在 2 周内没有收到答复

4

1 回答 1

2

这可能与您的使用有关caches.default,而不是使用caches.open("whatever"). 当您使用 时caches.default,您将共享自己使用的相同缓存fetch()。因此,当您的工作人员运行时,您的工作人员会检查缓存,然后fetch()检查缓存,然后fetch()再写入缓存,然后您的工作人员也会写入相同的缓存条目。由于写入操作特别是异步发生的(当响应流通过时),它们很可能重叠并且缓存变得混乱并将它们全部扔掉。

为避免这种情况,您应该打开一个私有缓存命名空间。所以,替换这一行:

let cache = caches.default;

和:

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

(这await总是立即完成;它只是需要,因为 Cache API 标准坚持认为此方法是异步的。)

这样,您正在读取和写入与fetch()本身读取/写入的缓存条目完全分开的缓存条目。

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


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

于 2020-06-13T00:54:45.293 回答