# 使用缓存
工作者提供了一种使用Cloudflare的经典CDN以及私有缓存空间来自定义缓存行为的方法。要了解缓存的好处,请参阅我们的学习中心关于“[什么是缓存?”](https://www.cloudflare.com/learning/cdn/what-is-caching/)的文章[。](https://www.cloudflare.com/learning/cdn/what-is-caching/)
## 与Cloudflare缓存交互
从概念上讲,有两种使用工作器与Cloudflare的Cache进行交互的方式:
* 将响应存储在Cloudflare的经典CDN上,可以通过调用`fetch()`Workers脚本来完成。通过Worker进行的自定义缓存行为包括:
* 设置Cloudflare缓存规则(即对cf对象进行操作)
* 设置自定义缓存头(即缓存控件)。这可能会影响浏览器以及Cloudflare缓存行为。
* 使用来自Workers脚本的Cache API,将响应存储在与Cloudflare的传统缓存分开的区域范围的命名空间中。甚至可以控制没有代理到Cloudflare的资产的缓存行为。
我们将不在本文中讨论,但其他控制Cloudflare缓存的方法包括:页面规则和Cloudflare缓存设置。如果您希望避免编写一些具有一定控制粒度的Javascript,我强烈建议您阅读“[如何控制Cloudflare的缓存”一文](https://support.cloudflare.com/hc/en-us/articles/202775670)。
### [缓存API](https://developers.cloudflare.com/workers/reference/apis/cache)
缓存API使用Cloudflare的全球网络为每个区域创建一个专用的缓存密钥名称空间。缓存对象存储在处理请求的本地数据中心中,不会复制到其他数据中心。
**缓存API与`fetch()`有何不同?**`fetch()`请求一个URL并根据您的Cloudflare设置自动应用缓存规则。它不允许您在对象到达缓存之前对其进行修改,或者在发出请求之前检查对象是否在缓存中。
缓存API的`caches.default`缓存对象使您可以:
* 当(且仅)使用缓存URL时,获取URL的响应`caches.default.match(..)`。
* 使用`caches.default.put(..)`和显式删除将响应明确存储在缓存中`caches.default.delete(..)`。
**缓存API的使用限制是什么?**
* 每个请求共50个`put()`,`match()`或`delete()`呼叫,使用与相同的配额`fetch()`
* `put()`每个请求总共5 GB
* 免费,专业版,商务版:
* 每个`put()`具有有效`Content-Length`标头的最大512MB
* 高达512MB的`put()`使用`Transfer-Encoding: chunked`。请注意,这会阻止后续`put()`的,直到传输完成。
* 对于企业:
* 每个`put()`带有有效`Content-Length`标头的最大5GB
* 高达5GBs了`put()`与`Transfer-Encoding: chunked`。请注意,这会阻止后续`put()`的,直到传输完成。
使用缓存API*不会*设置`Cf-Cache-Status`标头。
### Cloudflare的CDN
默认情况下,Cloudflare的传统CDN即使没有使用Worker也可以在静态资产上运行。尽管两者都存在于Cloudflare的全球网络中,但Cache API使用的命名空间与Cloudflare的CDN分开存储。
在Workers的上下文中[`fetch`](https://developers.cloudflare.com/workers/reference/apis/fetch),运行时提供的与传统Cloudflare缓存进行通信。首先,`fetch`检查URL是否与其他区域匹配。如果是这样,它将读取该区域的缓存。否则,即使URL是针对非Cloudflare站点的,它也会读取其自身区域的缓存。缓存设置`fetch`基于您的Cloudflare设置自动应用缓存规则。`fetch`不允许您在*对象*到达缓存之前对其进行*修改或检查*,但是允许您修改对象的*缓存方式*。
当响应填充高速缓存时,响应标头包含`CF-Cache-Status: HIT`。您可以告诉一个对象是否正在尝试缓存(如果有人看到)`CF-Cache-Status`。
Phew ..听起来很多,但是一些示例应该会很有道理。以下是根据给定请求自定义Cloudflare CDN的缓存行为的方法:
#### 缓存HTML(或其他未列入白名单的文件扩展名):
~~~javascript
// Force Cloudflare to cache an asset
fetch(event.request, { cf: { cacheEverything: true } })
~~~
将缓存级别设置为“缓存一切”将覆盖资产的默认“可缓存性”。对于TTL,Cloudflare仍将依赖由原点设置的标头。
#### 覆盖TTL:
~~~javascript
// Force response to be cached for 300 seconds.
fetch(event.request, { cf: { cacheTtl: 300 } })
~~~
此选项强制Cloudflare缓存此请求的响应,而不管响应上看到什么标头。这等效于设置两个页面规则:[“边缘缓存TTL”](https://support.cloudflare.com/hc/en-us/articles/200168376-What-does-edge-cache-expire-TTL-mean-)和[“缓存级别”(以“缓存所有内容”)](https://support.cloudflare.com/hc/en-us/articles/200172266-What-do-the-custom-caching-options-mean-in-Page-Rules-)。
#### 根据起点响应代码进行覆盖:
*此功能仅适用于企业用户。*
~~~javascript
// Force response to be cached for 86400 seconds for 200 status codes, 1 second for 404,
// and do not cache 500 errors
fetch(request, { cf: { cacheTtlByStatus: { '200-299': 86400, 404: 1, '500-599': 0 } } })
~~~
此选项是功能的一个版本,该`cacheTtl`功能根据响应的状态码选择TTL。如果对此请求的响应具有匹配的状态代码,则Cloudflare将在指令时间内进行缓存,并覆盖原始服务器发送的缓存指令。
TTL值:
* TTL正值表示以秒为单位的Cloudflare应该为之缓存资产多长时间
* `0`TTL将导致资产被缓存,但会立即过期(每次都从原始位置重新验证)
* `-1`,否则任何负值将指示Cloudflare根本不缓存
#### 自定义缓存键
*此功能仅适用于企业用户。*
一个请求的缓存键决定了两个请求是否“相同”以进行缓存。如果一个请求与先前的某个请求具有相同的缓存键,那么我们可以为两个请求提供相同的缓存响应。有关缓存键的更多信息,请参见[使用自定义缓存键](https://support.cloudflare.com/hc/en-us/articles/115004290387)支持文章。
~~~javascript
// Set cache key for this request to "some-string".
fetch(event.request, { cf: { cacheKey: 'some-string' } })
~~~
通常,Cloudflare根据请求的URL计算请求的缓存密钥。但是有时候,出于缓存目的,您希望将不同的URL视为相同。例如,假设您的网站内容同时由Amazon S3和Google Cloud Storage托管-您在两个地方都拥有相同的内容,并且使用Worker来在两者之间随机平衡。但是,您不想最终缓存内容的两个副本。您可以利用自定义缓存键基于原始请求URL而不是子请求URL进行缓存:
~~~javascript
addEventListener('fetch', event => {
let url = new URL(event.request.url)
if (Math.random() < 0.5) {
url.hostname = 'example.s3.amazonaws.com'
} else {
url.hostname = 'example.storage.googleapis.com'
}
let request = new Request(url, event.request)
event.respondWith(
fetch(request, {
cf: { cacheKey: event.request.url },
}),
)
})
~~~
请记住,代表不同区域进行操作的Worker不能影响彼此的缓存。仅在您自己的区域内发出请求时(在上面的示例中`event.request.url`是存储的键),或对不在Cloudflare上的主机的请求时,您才能覆盖缓存键。向另一个Cloudflare区域(例如,属于另一个Cloudflare客户)发出请求时,该区域将完全控制如何在Cloudflare中缓存其自身的内容;您无法覆盖它。
### 覆盖浏览器缓存(缓存控制标头)
浏览器通过Cloudflare发送的响应标头确定要缓存的内容。
~~~javascript
async function fetchAndApply(request) {
let response = await fetch(request)
// Make response headers mutable
response = new Response(response.body, response)
response.headers.set('Cache-Control', 'max-age=1500')
return response
}
~~~
- 关于本翻译文档
- 快速开始
- 模版库
- 讲解
- Workers页面
- 从0开始
- 从已有页面开始
- 从已有Worder开始
- 工具
- Cli工具 wrangler
- 安装
- 指令
- 配置
- 环境
- Webpack
- 密钥
- KV
- 网站
- Playground
- ServerLess插件
- Terraform
- REST API
- Making Requests
- Scripts
- Bindings
- Routes
- Integrations
- 相关
- 工作原理
- 安全
- 使用缓存
- 价格
- Routes
- Limits
- 提示
- 调试技巧
- 调试header
- FetchEvent生命周期
- 请求上下文
- 请求sign
- 参考
- runtime API
- Web Standards
- fetch
- fetchEvent
- Response
- Request
- KV
- Environment Variables
- Streams
- Encoding
- Web Crypto
- Cache API
- HTMLRewriter
- Workers KV
- Use cases
- Namespaces