HTTP 缓存简析

HTTP 缓存简析

💡 原文中文,约3400字,阅读约需8分钟。
📝

内容提要

HTTP缓存由Cache-Control控制:no-store不缓存,no-cache每次校验,max-age设定新鲜期;过期后浏览器用ETag或Last-Modified向服务器校验,未变返回304,变了重新下载。F5强制校验,Ctrl+F5完全绕过缓存。前端可用入口文件不缓存、静态资源加哈希长缓存实现版本更新。

🔎

延伸解读

强缓存与协商缓存的区别

文章将新鲜度(Freshness)对应强缓存,校验(Validation)对应协商缓存。强缓存下,浏览器直接使用本地缓存,不请求服务器;协商缓存则需向服务器校验,未变化返回304,变化则重新下载。理解这一区别有助于合理设置Cache-Control,平衡性能与资源更新。

no-cache与no-store的常见误解

文章特别指出,no-store才是完全不缓存,而no-cache实际会缓存但每次使用前都校验。这一命名容易让人混淆,开发者需注意:若不想缓存任何内容,应使用no-store;若希望每次校验,则用no-cache。错误使用可能导致不必要的请求或缓存失效。

刷新行为对缓存的影响

用户按F5会无视新鲜度发起校验,但若设置了immutable,浏览器仍可能使用缓存;Ctrl+F5则强制添加no-cache,直接获取最新资源。了解这些行为有助于调试缓存问题,避免因刷新方式不同而误判缓存策略效果。

前端版本更新的缓存实践

文章建议入口文件不缓存或每次校验,确保依赖最新;静态资源设置长max-age且不校验,并通过文件名哈希实现版本更新。这样既能长期缓存静态资源,又能在发布新版本时自动获取新文件,解决刷新后仍是旧数据的问题。

❓

Q&A

HTTP缓存中的强缓存和协商缓存分别对应什么概念?

强缓存对应新鲜度(Freshness),即缓存未过期时直接使用;协商缓存对应校验(Validation),即缓存过期后向服务器验证资源是否有效。

Cache-Control的no-store和no-cache有什么区别?

no-store表示完全不缓存;no-cache表示缓存资源,但每次使用前都必须向服务器校验。

浏览器如何通过ETag和Last-Modified进行缓存校验?

响应头有ETag时,下次请求会带If-None-Match,值为ETag;没有ETag时,可能带If-Modified-Since,值为Last-Modified。服务器根据这些值判断资源是否变化,未变返回304,变了返回200并重新下载。

按F5和Ctrl+F5刷新时,浏览器缓存行为有什么不同?

按F5会无视新鲜度发起校验,但如果Cache-Control设置了immutable,浏览器仍会使用缓存;按Ctrl+F5则完全绕过缓存,浏览器自动在请求头添加no-cache,强制从服务器获取最新数据。

前端如何配置缓存以实现版本更新后用户能获取最新资源?

入口文件不缓存或每次校验,确保依赖最新;静态资源(JS/CSS)设置长时间max-age且不校验,并在文件名中加入哈希值,这样版本更新后请求新文件,实现长缓存和版本更新。

什么是启发式缓存(Heuristic Caching)?

当服务器没有设置Cache-Control或max-age时,浏览器会根据Last-Modified推测请求的新鲜度,自动进行缓存,这被称为启发式缓存。

🏷️

标签

➡️

继续阅读