问题
每次发布 web 项目新的版本后, 在浏览器中打开项目时, 不清除浏览器缓存, 无法获取最新页面。
原因
为了减少资源请求次数,加快资源访问速度, 浏览器会对资源文件如图片 、css 文件、 js 文件等进行缓存, 浏览器缓存策略有强制缓存和协商缓存。
强制缓存 ---通过 HTTP 响应头中的特定字段来控制的 。这些字段通常包括 Expires 和 Cache-Control, 它们指示了资源的缓存有效时间 。 当浏览器在有效时间内再次请求同一资 源时, 它会直接从本地缓存中获取该资源, 而不会向服务器发送请求。
1 、 Expires: 在 HTTP 1.0 版本中, 通过 Expires 响应头来实现强制缓存 。 Expires 表 示未来资源会过期的时间点。如果当前时间超过了 Expires设定的时间,资源缓存时间到期, 浏览器会重新向服务器请求资源。
2 、Cache-Control: 在 HTTP 1.1 版本中, 引入了 Cache-Control 响应头, 它提供了更 灵活的缓存控制机制 。 例如, 可以通过 max-age 参数设置缓存的最大生存时间 (以秒为单 位), 如 Cache-Control: max-age= 1200 表示缓存有效时间为 1200 秒。
3 、启发式缓存: 如果响应头中没有设置任何缓存相关的字段, 浏览器会采用启发式算 法来决定是否缓存资源 。这通常是基于响应头中的 Date 和 Last-Modified 值来计算的。
协商缓存 ---是浏览器与服务器之间进行通信以确认缓存资源是否仍然有效的过程,协商 缓 存 主 要 涉 及 两 组 HTTP 头 字 段 : ETag 和 If-None-Match , 以 及 Last-Modified 和 If-Modified-Since 。它们的工作原理如下
1 、 ETag/If-None-Match: 当浏览器第一次请求某个资源时, 服务器会返回一个 ETag (实体标签),它是一个资源版本的唯一标识符。浏览器在后续请求该资源时,会在请求头 中携带 If-None-Match 字段, 其值为先前接收到的 ETag 。服务器会根据这个值来判断资源 是否有更新 。如果有更新, 服务器会返回新的资源和新的 ETag; 如果没有更新, 服务器会 返回 304 Not Modified 状态码, 告诉浏览器可以使用缓存中的资源。
2 、Last-Modified/If-Modified-Since: 类似于 ETag 机制, 但 Last-Modified 记录的是资 源最后修改的时间。浏览器在后续请求时,会在请求头中携带 If-Modified-Since 字段,其值 为先前接收到的 Last-Modified 时间 。服务器会检查资源的最后修改时间是否在这个时间之 后。如果是,说明资源有更新,服务器会返回新资源和新的 Last-Modified 时间;如果不是, 服务器同样会返回 304 Not Modified 状态码。
3 、协商缓存的目的是确保浏览器能够获取最新的资源, 同时避免不必要的数据传输 。 这种机制特别适用于那些可能被频繁更新的资源,如在线商城的商品信息、社交媒体的动态 等 。通过协商缓存, 可以在不牺牲内容新鲜度的前提下, 提高网站的性能和用户体验
检查时机****:**** 在浏览器加载资源时,会先检查强缓存是否命中。如果强缓存中有该资源的 副本且未过期, 则直接使用, 不会发送 HTTP 请求到服务器 。 只有当强缓存未命中或资源 已过期时, 浏览器才会进行协商缓存, 即向服务器发送 HTTP 请求以确认资源是否有更新。
应用场景 : 强制缓存适用于不经常变动的静态资源, 如图片 、CSS 和 JavaScript 文件。
这些资源的变更频率较低,因此可以设置较长的缓存时间,以提高加载速度并减少服务器压 力。协商缓存则适用于那些可能被频繁更新的资源,通过服务器的验证确保用户能够获取最 新的资源内容
解决方案
1 、添加版本号到静态资源:在引用静态资源时, URL 后面添加查询参数,参数为新版 本号, 例如:
javascript
window.location.href = `${url}?v=${版本号}`;
2 、在 webpack 中, 通过添加时间戳/版本号等, 配置 js 和 css 打包配置, 例如:
javascript
const Timestamp = new Date().getTime();
configureWebpack:{
output:{
filename : 'js/[name].[hash:8].' + Timestamp + '.js',
chunkFilename: 'js/[name].[hash:8].' + Timestamp + '.js'
},
...
}
3 、设置 HTTP 头信息: 通过服务器配置, 设置 HTTP 头信息来控制浏览器缓存行为。
4 、通过服务器配置: 可以通过服务器配置, 比如 Nginx 或 Apache, 设置对静态资源 的缓存控制。