这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战
什么是浏览器缓存:
浏览器缓存就是把一个已经请求过得web资源(如HTML页面,图片,js,数据)拷贝一份副本储存在浏览器中。缓存会根据进来的请求保存输出内容的副本。 当下一个请求来到的时候,如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。比较常见的就是浏 览器会缓存访问过网站的网页,当再次访问这个URL地址的时候,如果网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明 确标识资源已经更新,浏览器才会再次下载网页。
为什么进行浏览器缓存:
(1)减少网络带宽消耗;
(2)降低服务器压力;
(3)减少网络延迟,加快页面打开速度;
浏览器缓存的控制:
(1)使用meta标签:<meta http-equiv="Pragma" content="no-cache"> 上述代码告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。但是只有IE才能识别这段meta标签含义,其它主流浏览器仅识别“Cache-Control: no-store”的meta标签。
(2)CDN缓存 用户通过输入域名来访问页面,首先进行dns处理,dns解析服务器会将用户访问请求定位到离用户最近、负载最轻的cdn缓存服务器上,返回该cdn节点的ip地址,缓存服务器拿到数据后, 一方面将数据返回浏览器,另一方面进行本地保存,之后再次访问,数据将从cdn缓存服务器中被返回。
(3)本地存储
cookie数据超过4K会怎样?
在百度中进行了测试,导致网页无法正常访问。
浏览器的缓存策略:
通常浏览器缓存策略分为两种:强缓存和协商缓存,并且缓存策略都是通过设置 HTTP Header 来实现的。
图:第一次HTTP请求
强缓存:
不会向服务器发送请求,直接从缓存中读取资源,该请求返回200的状态码,并且Size显示from disk cache或from memory cache。
查看了Wiki的相关请求,可以发现,有些数据是直接从硬盘中存储的信息中读取的,而有的则是从服务端获取的数据。
强缓存可以通过设置两种 HTTP Header 实现:Expires 和 Cache-Control。 其中,Expires是http1.0的产物;cache-control是http1.1的产物;两者同时存在的时候,后者的优先级高; Expires:缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。 Cache-Control: 其值有public:表示响应可以被客户端与代理服务器缓存; private:表示响应只能被客户端缓存;默认取值即是private; max-age=30,表示缓存30秒后过期,需要重新发送请求。下述Wiki的请求中,max-age值为315360000,表示本次请求的这些时间之内,再次发送相同请求的时候,会直接命中强缓存。 no-store:不缓存任何响应;既不命中强缓存,也不命中协商缓存; no-cache:资源被缓存,但是会立即失效,当下次再发送同样的请求的时候,会验证资源是否过期了;客户端缓存内容,是否使用缓存则需要经过协商缓存来验证决定。表示不使用 Cache-Control的缓存控制方式做前置验证,而是使用 Etag 或者Last-Modified字段来控制缓存。
协商缓存:
表示强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
协商缓存可以通过设置两种 HTTP Header 实现:Last-Modified 和 ETag (由服务器生成)。
Last-Modified:浏览器在第一次访问资源时,服务器返回资源的同时,在response header中添加 Last-Modified的header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和header; 浏览器下一次请求这个资源,浏览器检测到有 Last-Modified这个header,于是添加If-Modified-Since这个header,值就是Last-Modified中的值;服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304和空的响应体,直接从缓存读取,如果If-Modified-Since的时间小于服务器中这个资源的最后 修改时间,说明文件有更新,于是返回新的资源文件和200。
Etag是服务器响应请求时,返回当前资源文件的一个唯一标识,只要资源有变化,Etag就会重新生成。 浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源 的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。如果服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端; 如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。
图:协商缓存生效,返回304和Not Modified
图:协商缓存失效,返回200和请求结果
总结浏览器的缓存机制:
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),
协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回304,继续使用缓存。
图:浏览器的缓存机制
当强制刷新页面的时候,是不使用缓存的,这个时候,发送的请求头里面如右图,服务器返回200的状态码和最新的内容。
在地址栏中输入网址的时候,会查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。