Workers 的设计和构建基于 Cloudflare 全球网络,使开发者能够直接与 Cloudflare cache 交互。cache 可提供临时的、数据中心本地的存储,作为频繁访问静态或动态内容的便捷方式。
通过允许开发者写入 cache,Workers 提供了一种在 Cloudflare CDN 上自定义 cache 行为的方式。要了解缓存的优势,请参阅 Learning Center 关于什么是缓存? ↗的文章。
Cloudflare Workers 在 cache 之前运行,但也可用于修改从 cache 返回的资源。修改从 cache 返回的资源可以在减少源站负载和降低最终用户延迟(通过从附近位置提供资源)的同时,实现响应签名或个性化。
从概念上讲,使用 Worker 与 Cloudflare Cache 交互有两种方式:
-
在 Workers 脚本中调用
fetch()。通过 Cloudflare 代理的请求即使不使用 Workers 也会根据 zone 的默认或配置行为进行缓存(例如,以.jpg结尾的静态资源等文件默认会被缓存)。Workers 可以通过以下方式进一步自定义此行为:- 设置 Cloudflare cache 规则(即操作 request 的
cf对象)。
- 设置 Cloudflare cache 规则(即操作 request 的
-
在 Workers 脚本中使用 Cache API 存储响应。这允许缓存非来自源站的响应,并通过以下方式提供更精细的控制:
-
通过设置传递给
cache.put()的响应上的Cache-Control等 header 来自定义任何资源的 cache 行为。 -
通过
cache.put()缓存 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 中的资源可以通过以下几种方式清除:
-
在 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。
在 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 可视为临时 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:0header 且无法更改。您可以克隆Response,将 header 调整为max-age=3600值,然后使用 Cache API 保存修改后的Response一小时。 -
当您想以编程方式从 cache 访问
Response而不依赖fetch请求时。例如,您可以检查是否已缓存https://example.com/slow-response端点的Response。如果是,可以避免慢请求。