【问题标题】:Trouble with Cloudflares Worker Cache APICloudflares Worker Cache API 出现问题
【发布时间】:2020-10-02 19:41:11
【问题描述】:

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

值得注意的是,这个 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 周内没有收到答复

【问题讨论】:

    标签: javascript service-worker cloudflare cloudflare-workers cacheapi


    【解决方案1】:

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

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

    let cache = caches.default;
    

    与:

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

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

    这样,您正在读取和写入一个完全独立于 fetch() 本身读取/写入的缓存条目。

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


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

    【讨论】:

    • 不幸的是,这并没有解决问题,请求仍然从未从缓存中提供。我按照您的建议使用私有缓存更新了问题中的代码。
    • 也许需要进一步澄清:我基本上是在尝试使用从图像请求中的 cookie 派生的特定授权标头缓存 API 的响应代码,以检查用户是否是允许查看图像,并沿途缓存所有内容以减少后端负载并缩短网站加载时间。
    • 通过再次使用字符串缓存键而不是我尝试使用的请求对象来使其工作 - 不幸的是仍然不知道为什么,但我认为如果没有你的回答,这将无法工作所以无论哪种方式我都会接受。
    • @user13737110 有趣的是,使用字符串键应该等同于使用由该字符串构造的没有标题的Request 对象。因此,这与您发布的代码之间的唯一区别是 Authorization 标头的存在。 Authorization 标头的存在可能会导致 Cloudflare 的缓存决定响应不可缓存。这样的规则对于普通的 HTTP 请求是有意义的,但在使用缓存 API 时可能不是。我将提出一个问题来调查这个......但听起来你有一个适合你的情况的解决方案。
    • 是的,可能是这样。我通过使用请求 URL 作为缓存键来“解决”它,将 auth 标头中的令牌作为假查询参数附加。我希望 Request 对象中的 Authorization 标头会产生一个唯一的缓存键,因为文档只提到 Set-Cookie 标头使响应无法缓存。
    猜你喜欢
    • 2021-05-02
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 2019-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多