北京奇天大胜网络科技有限公司 010-
北京市昌平区北清路1号珠江摩尔3号楼1单元1513
版权声明:本文为博主原创文章,遵循 版权协议,转载请附上原文出处链接和本声明。
发布一个新版本页面后,如果未加干预,用户往往还会看到更新前的样式,这就是浏览器端的缓存在“捣乱”了,本文写于2020年3月,介绍浏览器的缓存机制,还会告诉你如何在需要的时候使用或丢弃缓存。
我们知道,前端代码100%地运行在浏览器端,当用户打开一个页面时,需要下载 html, js, css 和一堆图片,页面在短期内一般不会有改变,通常,浏览器会聪明地记录这些静态资源的相关信息,保存在临时目录中的css和图片等等,都不会被删除,这就是缓存的一种。当用户再次访问同样的页面时,浏览器会优先使用缓存,找不到缓存时,才会从互联网重新下载。此时虽然页面的样式已经在服务端更新了,但浏览器认为本地已经有了这份样式,就不会再重新下载新样式,用户看到的就是老版本的页面了。
要想更好地利用缓存,我们需要知道缓存的工作方式。
缓存是在服务器响应浏览器发出的请求时建立的,每次浏览器发送请求时,都会先尝试寻找缓存,拿到服务器发送的响应后,再根据响应报文中的缓存标识来决定是否要建立缓存。
浏览器的缓存分为两种:强缓存和协商缓存
强缓存就是指,浏览器不向服务端发送请求,直接从缓存读取信息,这时对应的请求会返回状态码200 。
这个字段是一个GMT格式的字符串,比如Mon, Mar 09 :29 GMT,如果发送请求时,时间(本地时间)超过了这个时间,那么缓存就会失效,浏览器会到服务器去获取资源,否则缓存有效,返回状态码304 。
强缓存只依赖本地的信息来判断缓存是否有效,有时我们需要由服务端来决定是否使用缓存,这时候就要用到协商缓存。
客户端再次发送请求时,会用上一次返回的 Last-Modified 的值作为 If-Modified-Since,服务端接收到请求后,如果发现请求头中含有 If-Modified-Since,则会把这两个值对比,如果服务器上资源的修改时间大于 If-Modified-Since,则返回新的资源,状态码为200,否则返回状态码304,通知客户端使用缓存 。
如果没有命中缓存,那么响应中的 Last-Modified 会被更新,反之则不更新。
客户端再次发送请求时,用上次返回的 Etag 作为 If-None-Match 带在请求头中,服务端接收到请求后,如果发现请求头中含有 If-None-Match,则会把 If-None-Match 与资源文件的Etag值做对比,如果相同,则返回304,使用缓存,否则返回新资源,状态码为200 。
无论是否命中缓存,响应中都会返回 Etag,如果命中了缓存,则返回的 Etag 与上次相同。
这张图大致描述了浏览器选择缓存的流程:
打开浏览器的开发者工具,可以直观地观察缓存的启用,这里以chrome的dev-tool为例。
从 status 和 size 可以看出,这些资源命中了缓存,memory cache是指缓存保存在内存中,关闭浏览器时缓存就释放掉了,一般脚本,图片是这种方式缓存的,还有一种存储方式是 disk cache,说明缓存保存在硬盘中,关闭浏览器后缓存不会释放,一般css会用这种方式缓存:
发布新版本后,我们系统客户端能及时更新,如果请求的url不同,则不会命中缓存。可以在webpack配置中这样写:
script标签中的src,link标签中的href,都可以在路径后面拼上 ?xxx
,拼接参数不会影响资源访问,但可以起到改变url丢弃缓存的目的。
如果你是一个用户,可以用以下任意一种方法来丢弃缓存:
清空缓存并进行硬刷新
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。