内容提要
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推测请求的新鲜度,自动进行缓存,这被称为启发式缓存。