浅析浏览器的缓存机制

由于公司没外网,好久没写技术博客了,几天无聊写一下浏览器缓存机制,以及如何禁止缓存。

个人理解:

    浏览器第一次访问一个地址时会缓存静态文件(html,css,js),然后当第二次访问时会查看缓存是否过期,如果没有过期不会重新下载网页,直接使用缓存中的网页。只有网站明确标明已经更新了,浏览器才会重新下载网页。

 HTTP缓存机制:

      当浏览器向服务端发送请求或者下载静态文件时会根据Response Header里面的Cache-Control和expires两个属性来判断是否读取缓存中的数据,其中Cache-Control的优先级高。

      Cache-Control对应的值:

          Public:指示响应可被任何缓存区缓存。

          Private:指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。

          no-cache:指示请求或响应消息不能缓存

          no-store:用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。

          max-age:指示浏览器可以接收生存期不大于指定时间(以秒为单位)的响应。

          min-fresh:指示浏览器可以接收响应时间小于当前时间加上指定时间的响应。

      具体步骤:

        ①浏览器第一次访问服务器资源 /index.html

          在浏览器中没有缓存文件,直接向服务器发送请求。

          服务器返回 200 OK,实体中返回 index.html文件内容,并设置一个缓存过期时间,一个文件修改时间,一个根据index.html内容计算出来的实体标记Entity Tag,简称Etag。

          浏览器将/index.html路径的请求缓存到本地。

          ②浏览器第二次访问服务器资源 /index.html

          由于本地已经有了此路径下的缓存文件,所以这一次就不直接向服务器发送请求了。

          首先,进行缓存过期判断。浏览器根据①中设置缓存过期时间判断缓存文件是否过期。

          情景一:若没有过期,则不向服务器发送请求,直接使用缓存中的结果,此时我们在浏览器控制台中可以看到 200 OK(from cache) ,此时的情况就是完全使用缓存,浏览器和服务器没有任何交互的。

          情景二:若已过期,则向服务器发送请求,此时请求中会带上①中设置的文件修改时间,和Etag

          然后,进行资源更新判断。服务器根据浏览器传过来的文件修改时间,判断自浏览器上一次请求之后,文件是不是没有被修改过;根据Etag,判断文件内容自上一次请求之后,有没有发生变化

          情形一:若两种判断的结论都是文件没有被修改过,则服务器就不给浏览器发index.html的内容了,直接告诉它,文件没有被修改过,你用你那边的缓存吧—— 304 Not Modified,此时浏览器就会从本地缓存中获取index.html的内容。此时的情况叫协议缓存,浏览器和服务器之间有一次请求交互。

          情形二:若修改时间和文件内容判断有任意一个没有通过,则服务器会受理此次请求,之后的操作同①

   服务端: 

      服务端通过If-Modified-Since(Last-Modified)和If-None-Match(Etag)这两个属性的值来判断缓存是否失效的。

         Last-Modified/If-Modified-Since

      Last-Modified/If-Modified-Since要配合Cache-Control使用。

      Last-Modified:响应资源的最后修改时间。

      If-Modified-Since:当缓存过期时,发现资源具有Last-Modified声明,则在请求头带上If-Modified-Since(值就是Last-Modified)。服务器收到请求后发现有头If-Modified-Since则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应HTTP 200整片资源内容(写在响应消息包体内);若最后修改时间较旧,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

      Etag/If-None-Match

          Etag/If-None-Match也要配合Cache-Control使用。

          Etag:资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。

          If-None-Match:当缓存过期时,发现资源具有Etage声明,则在请求头带上If-None-Match(值就是Etag)。服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。

      前端控制禁止缓存:   

         1、在html 头部加上如下代码:

                     <META HTTP-EQUIV="pragma" CONTENT="no-cache">

                     <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">

                     <META HTTP-EQUIV="expires" CONTENT="0">

             这样所有的js 文件都不会被缓存。

      2、清楚form表单里的临时缓存

        <body onLoad="javascript:document.yourFormName.reset()">
        
yourFormName :表单名字
       其实form表单的缓存对于我们书写还是有帮助的,一般情况不建议清理,但是有时候为了安全问题等,需要清理一下!
      

      3、清除ajax缓存
      1.url地址上加上随机数
       url参数后加上"?ran="+Math.random;//ran随便取
       2、加上时间戳
        
"?timestamp=" + new Date().getTime();
      服务端禁止:
        在服务端加 header("Cache-Control: no-cache, must-revalidate")
 
  

 参考:https://www.haorooms.com/post/js_llq_hc/

    https://mp.weixin.qq.com/s?__biz=MjM5OTMxMzA4NQ==&mid=400875941&idx=2&sn=46101bbc366233024289492eaefa0e77&scene=21#wechat_redirect

posted @ 2019-05-21 21:37  关关大大  阅读(1161)  评论(0编辑  收藏  举报