更新 CFR2(CloudFlare R2)存储后浏览器仍显示旧内容,这通常是因为浏览器的本地缓存和 Cloudflare 的 CDN 缓存共同作用的结果。只清除其中一层,往往无法立即看到更新。
这里有几个步骤可以帮助你解决这个问题。
🎯 第一步:理解缓存的层级
首先需要明确,R2 存储的 TTL(生存时间)和浏览器的缓存是两回事。
- R2 的 TTL:控制的是 Cloudflare 边缘网络(CDN)对内容的缓存时长。
- 浏览器缓存:由服务器返回的 HTTP 响应头(如
Cache-Control)控制。浏览器只认这些头信息,不认 R2 的 TTL 设置。
因此,即使你在 R2 中更新了文件,如果浏览器缓存了旧版本,它可能根本不会去请求服务器,你自然也就看不到更新。
🛠️ 第二步:清除 Cloudflare CDN 缓存
这是让 Cloudflare 边缘节点获取新内容的第一步。
- 登录你的 Cloudflare 仪表盘(dash.cloudflare.com)。
- 选择对应的域名。
- 在左侧菜单中,点击 “缓存” (Cache) → “清除缓存” (Purge Cache)。
你可以选择:
- 清除所有内容 (Purge Everything):最直接,但会导致所有缓存被清空,可能短暂影响网站加载速度。
- 按 URL 清除 (Purge by URL):更精准,只清除特定文件的缓存。输入你更新过的文件或页面的完整 URL 即可。
注意:即使清除了 Cloudflare 缓存,全球各地的数据中心也需要时间来重新缓存你的文件。
🧹 第三步:清除浏览器缓存
清除 Cloudflare 缓存后,如果浏览器仍显示旧内容,就需要清除浏览器自身的缓存了。
- 通用方法:使用快捷键 Ctrl + Shift + Del (Windows) 或 Cmd + Shift + Delete (Mac) 打开清除浏览数据的窗口,选择清除缓存。
- 无痕模式测试:在浏览器的无痕/隐私模式下打开页面,如果能看到更新,说明问题基本确定是浏览器缓存引起的。
- 硬性重新加载:在页面上按 Ctrl + F5 (Windows) 或 Cmd + Shift + R (Mac),可以强制浏览器忽略缓存,从服务器重新加载资源。
⚙️ 第四步:配置正确的缓存头(根本解决方案)
这是从根源上控制浏览器缓存行为的关键,尤其当你通过 Cloudflare Workers 访问 R2 存储时。
问题根源:如果 Worker 在返回 R2 对象时,没有设置正确的 HTTP 头,浏览器可能不会缓存(或缓存行为不符合预期)。例如,流式响应(Streaming Response)或缺少 Content-Length 头,都可能导致 Chrome 等浏览器不进行磁盘缓存。
解决方案:在你的 Worker 代码中,为响应显式添加浏览器缓存相关的 HTTP 头。例如:
// 在获取R2对象后,设置响应头
const headers = new Headers();
headers.set('Cache-Control', 'public, max-age=31536000'); // 缓存一年
headers.set('Content-Type', object.httpMetadata.contentType);
// 确保包含 Content-Length 头
headers.set('Content-Length', object.size);
// 可以添加 ETag 便于验证
headers.set('ETag', object.httpMetadata.etag);
return new Response(object.body, { headers });
对于非 Range 请求(即完整文件请求),使用 await object.arrayBuffer() 可以获取非流式响应,这更有利于浏览器进行磁盘缓存。
💡 额外调试建议
- 开启开发模式:在 Cloudflare 仪表盘的“缓存”设置中,可以开启“开发模式”(Development Mode)。它会暂时绕过缓存,让你直接看到源站的最新内容,方便测试。
- 检查响应头:使用浏览器开发者工具(按 F12)的“网络”(Network) 面板,查看文件的响应头,确认
Cache-Control等头信息是否符合你的预期。
💎 总结
遇到此类问题,可以按以下流程排查:
- 首先,在无痕模式下访问页面,确认问题是否由浏览器缓存引起。
- 其次,在 Cloudflare 仪表盘清除对应 URL 或全部缓存。
- 然后,清除浏览器缓存或进行硬性重新加载。
- 最后,检查并修正你的 R2 访问逻辑(尤其是通过 Worker 时),确保返回了正确的
Cache-Control等 HTTP 头,这是长久之计。
