跳转到内容
搜索文档

Cache 工作原理

最后更新 查看 MarkdownAgent 设置

Workers 的设计和构建基于 Cloudflare 全球网络,使开发者能够直接与 Cloudflare cache 交互。cache 可提供临时的、数据中心本地的存储,作为频繁访问静态或动态内容的便捷方式。

通过允许开发者写入 cache,Workers 提供了一种在 Cloudflare CDN 上自定义 cache 行为的方式。要了解缓存的优势,请参阅 Learning Center 关于什么是缓存?的文章。

Cloudflare Workers 在 cache 之前运行,但也可用于修改从 cache 返回的资源。修改从 cache 返回的资源可以在减少源站负载和降低最终用户延迟(通过从附近位置提供资源)的同时,实现响应签名或个性化。

与 Cloudflare Cache 交互

从概念上讲,使用 Worker 与 Cloudflare Cache 交互有两种方式:

  • 在 Workers 脚本中调用 fetch()。通过 Cloudflare 代理的请求即使不使用 Workers 也会根据 zone 的默认或配置行为进行缓存(例如,以 .jpg 结尾的静态资源等文件默认会被缓存)。Workers 可以通过以下方式进一步自定义此行为:

    • 设置 Cloudflare cache 规则(即操作 requestcf 对象)。
  • 在 Workers 脚本中使用 Cache API 存储响应。这允许缓存非来自源站的响应,并通过以下方式提供更精细的控制:

    • 通过设置传递给 cache.put() 的响应上的 Cache-Control 等 header 来自定义任何资源的 cache 行为。

    • 通过 cache.put() 缓存 Worker 本身生成的响应。

清除 Worker 缓存的单文件资源

使用单文件清除来清除 Worker 缓存的资源时,请确保不要清除最终用户 URL。相反,应清除 fetch 请求中的 URL。例如,您有一个在 https://example.com/hello 上运行的 Worker,该 Worker 向 https://notexample.com/hello 发起 fetch 请求。

就 cache 而言,fetch 请求中的资源(https://notexample.com/hello)才是被缓存的资源。要清除它,您需要清除 https://notexample.com/hello

清除最终用户 URL https://example.com/hello 不会生效,因为那不是 cache 看到的 URL。您需要在 Worker 中确认实际 fetch 的 URL,以便清除正确的资源。

在上例中,https://notexample.com/hello 未通过 Cloudflare 代理。如果 https://notexample.com/hello 通过 Cloudflare 代理(orange-clouded),则您必须拥有 notexample.com 并从 notexample.com zone 清除 https://notexample.com/hello

为更好地理解此示例,请查看以下图表:

flowchart TD
accTitle: Single file purge  assets cached by a worker
accDescr: This diagram is meant to help choose how to purge a file.
A("You have a Worker script that runs on <code>https://</code><code>example.com/hello</code> <br> and this Worker makes a <code>fetch</code> request to <code>https://</code><code>notexample.com/hello</code>.") --> B(Is <code>notexample.com</code> <br> an active zone on Cloudflare?)
    B -- Yes --> C(Is <code>https://</code><code>notexample.com/</code> <br> proxied through Cloudflare?)
    B -- No  --> D(Purge <code>https://</code><code>notexample.com/hello</code> <br> from the original <code>example.com</code> zone.)
    C -- Yes --> E(Do you own <br> <code>notexample.com</code>?)
    C -- No --> F(Purge <code>https://</code><code>notexample.com/hello</code> <br> from the original <code>example.com</code> zone.)
    E -- Yes --> G(Purge <code>https://</code><code>notexample.com/hello</code> <br> from the <code>notexample.com</code> zone.)
    E -- No --> H(Sorry, you can not purge the asset. <br> Only the owner of <code>notexample.com</code> can purge it.)

清除使用 Cache API 存储的资源

通过 Cache API 操作存储在 cache 中的资源可以通过以下几种方式清除:

  • 在 Worker 中调用 cache.delete 以使用匹配的 request 变量使该资源的 cache 失效。

    • 以这种方式清除的资源仅在执行 Worker 运行时的数据中心本地清除。
  • 要在全球范围内清除资源,请使用标准 cache purge 选项。根据 cache API 实现,并非所有 cache purge 端点都适用于清除 Cache API 存储的资源。

    • 可以使用 Purge Everything cache 操作清除 zone 上的所有资源。此清除操作将从所有数据中心的 cache 中移除与 Cloudflare zone 关联的所有资源,无论使用何种方法。

    • 可以通过在 Worker 中调用 response.headers.append() 并动态追加 Cache-Tag 值,动态向请求添加 Cache Tags。设置后,可以使用这些标签选择性地从 cache 中清除资源,而无需使 zone 上所有缓存资源失效。

  • 目前,无法清除 Worker 设置的自定义 cache key 的 URL。相反,请使用通过 Cache Rules 创建的自定义 key。或者,使用 purge everything、purge by tag、purge by host 或 purge by prefix 清除资源。

边缘与浏览器缓存

浏览器 cache 通过发送给客户端的响应中的 Cache-Control header 控制(handler 返回的 Response 实例)。Workers 可以通过在响应上设置此 header 来自定义浏览器 cache 行为。

本文档未提及的其他控制 Cloudflare cache 的方式包括:Page Rules 和 Cloudflare cache 设置。如果您希望避免编写 JavaScript 但仍需一定程度的控制,请参阅如何自定义 Cloudflare 的 cache

fetch

在 Workers 上下文中,运行时提供的 fetch 与 Cloudflare cache 通信。首先,fetch 检查 URL 是否匹配不同的 zone。如果是,则读取该 zone 的 cache(或 Worker)。否则,即使 URL 是非 Cloudflare 站点,也会读取其自身 zone 的 cache。fetch 上的 cache 设置会根据 Cloudflare 设置自动应用缓存规则。fetch 不允许在对象到达 cache 之前修改或检查它们,但允许修改其缓存方式。

当响应填充 cache 时,响应 header 包含 CF-Cache-Status: HIT。如果看到 CF-Cache-Status,说明对象正在尝试缓存。

模板展示了如何使用 fetch 在给定请求上自定义 Cloudflare cache 行为。

Cache API

Cache API 可视为临时 key-value 存储,其中 Request 对象(更具体地说,是 request URL)是 key,Response 是 value。

Cloudflare Cache 有两种 cache namespace 可用:

  • caches.default – 通过访问 caches.default 可以访问默认 cache(与 fetch 请求共享的同一 cache)。这在收到响应后需要覆盖已缓存内容时很有用。
  • caches.open() – 可以使用 let cache = await caches.open(CACHE_NAME) 访问命名空间 cache(与 fetch 请求共享的 cache 分开)。请注意 caches.open 是异步函数,与 caches.default 不同。

何时使用 Cache API:

  • 当您想以编程方式保存和/或从 cache 中删除响应时。例如,假设源站响应 Cache-Control: max-age:0 header 且无法更改。您可以克隆 Response,将 header 调整为 max-age=3600 值,然后使用 Cache API 保存修改后的 Response 一小时。

  • 当您想以编程方式从 cache 访问 Response 而不依赖 fetch 请求时。例如,您可以检查是否已缓存 https://example.com/slow-response 端点的 Response。如果是,可以避免慢请求。

模板展示了如何使用 cache API。有关 cache API 的限制,请参阅 Limits

相关资源

这篇文档对您有帮助吗?