zoukankan      html  css  js  c++  java
  • 浏览器缓存 总结

    阅读完这篇文章需要15分钟

    (2020.06.12) 

    总结:一共由四种 (20200518)

     

    强缓存:

    1.Expires

    2.Cache-Control:max-age (这是一个相对时间,优先级比expires高)

    协商缓存:

    1.if-modified-since (请求)   last-modified(响应)  (精确到秒)

    2.if-none-match(请求) e-tag(响应)  (优先级比if-modified-since/last-modified高)

    强缓存的优先级比协商缓存的优先级高。

    强缓存响应码200

    协商缓存响应码304

    总结一下
    (2018.10.18)

    Expires (绝对时间)

    Cache-Control 中的max-age (相对时间)

    If-Modified-Since
    Last-Modified


    Etag
    If-None-Match

      • 强缓存  expires 和cache-control中的max-age
        用户发送的请求,直接从客户端(浏览器)缓存中获取,不发送请求到服务器,不与服务器发生交互行为。

      • 协商缓存 e-tag if-none-match last-modified if-modified-since
        用户发送的请求,发送到服务器后,由服务器判定是否从缓存中获取资源。

      • 两者共同点:客户端获得的数据最后都是从客户端缓存中获得。

      • 两者的区别:从名字就可以看出,强缓存不与服务器交互,而协商缓存则需要与服务器交互。

    缓存相关header

    强缓存:

    ·Expires

      响应头,代表该资源的过期时间

    ·Cache-Control

      请求/响应头,缓存控制字段,精确控制缓存策略,其中max-age是相对过期时间

     

    协商缓存 :

    ·IF-Modifeid-since

      请求头,资源最近修改时间,由浏览器告诉服务器

     

    ·Last-Modified

      响应头,资源最近修改时间,由服务器告诉浏览器

    ·Etag

        响应头,资源标识,由服务器告诉浏览器

     

    · If-None-Match

       请求头,缓存资源标识,由浏览器告诉服务器

    配对使用的字段

       ·If-Modified-Since和Last-Modified

        ·Etag 和If-None-Match

    =================================================================================================

    Expires:

    浏览器第一次请求一个静态资源 a.js。(1KB)

    • 浏览器第一次请求一个静态资源 a.js。(1KB)
    • 服务器把 a.js 和 a.js 的缓存过期时间(Expires:Mon, 26 Sep 2018 05:00:00 GMT)发给浏览器。(10+1=11KB)

    服务器告诉浏览器:你把我发给你的 a.js 文件缓存到你那里,在 2018年9月26日5点之前不要再发请求烦我,直接使用你自己缓存的 a.js 就行了。

    • 浏览器接收到 a.js,同时记住了过期时间。
    • 在2018年9月26日5点之前,浏览器再次请求 a.js,便不再请求服务器,直接使用上一次缓存的 a.js 文件。(0KB)
    • 在2018年9月26日5点01分,浏览器请求 a.js,发现 a.js 缓存时间过了,于是不再使用本地缓存,而是请求服务器,服务器又重新读取磁盘文件 a.js,返给浏览器,同时告诉浏览器一个新的过期时间。(1+10+1=12KB   请求1个kb,返回10+1个kb)。
    • 如此往复。。。

    该种方式较之前的方式有了很大的改善:

    • 在过期时间以内,为用户省了很多流量。
    • 减少了服务器重复读取磁盘文件的压力。
    • 缓存过期后,能够得到最新的 a.js 文件。

    缺点还是有:

    • 缓存过期以后,服务器不管 a.js有没有变化,都会再次读取 a.js文件,并返给浏览器。

    =========================================================================================================

    服务器告诉浏览器资源上次修改时间。

    为了解决上个方案的问题,服务器和浏览器经过磋商,制定了一种方案,服务器每次返回 a.js 的时候,还要告诉浏览器 a.js 在服务器上的最近修改时间 Last-Modified (GMT标准格式)。

    • 浏览器访问 a.js 文件。(1KB)
    • 服务器返回 a.js 的时候,告诉浏览器 a.js 文件。(10+1=11KB) 在服务器的上次修改时间 Last-Modified(GMT标准格式)以及缓存过期时间 Expires(GMT标准格式)
    • 当 a.js 过期时,浏览器带上 If-Modified-Since(等于上一次请求的Last-Modified) 请求服务器。(1KB)
    • 服务器比较请求头里的 Last-Modified 时间和服务器上 a.js的上次修改时间:
      • 如果一致,则告诉浏览器:你可以继续用本地缓存(304)。此时,服务器不再返回 a.js 文件。(1KB)
      • 如果不一致,服务器读取磁盘上的 a.js 文件返给浏览器,同时告诉浏览器 a.js 的最近的修改时间 Last-Modified 以及过期时间 Expires。(1+10=11KB)
      • 如此往复。

    此种方案比上一个方案有了更进一步的优化:

    • 缓存过期后,服务器检测如果文件没变化,不再把a.js发给浏览器,省去了 10KB 的流量。
    • 缓存过期后,服务器检测文件有变化,则把最新的 a.js 发给浏览器,浏览器能够得到最新的 a.js。

    缺点:

    • Expires 过期控制不稳定,因为浏览器端可以随意修改时间,导致缓存使用不精准。
    • Last-Modified 过期时间只能精确到秒。

    精确到秒存在两个问题:

    • 1、如果 a.js 在一秒时间内经常变动,同时服务器给 a.js 设置无缓存,那浏览器每次访问 a.js,都会请求服务器,此时服务器比较发给浏览器的上次修改时间和 a.js 的最近修改时间,发现都是在同一时间(因为精确到秒),因此返回给浏览器继续使用本地缓存的消息(304),但事实上服务器上的 a.js 已经改动了好多次了。所以这种情况,浏览器拿不到最新的 a.js 文件。
    • 2、如果在服务器上 a.js 被修改了,但其实际内容根本没发生改变,会因为 Last-Modified 时间匹配不上而重新返回 a.js 给浏览器。

    =============================================================================================================================

    注: cache-control与exipire的区别:

    cache-control的max-age是相对时间 expire是绝对时间

    cache-control除了max-age字段还有一些别的字段起别的作用

    继续改进,增加相对时间的控制,引入 Cache-Contorl

    为了兼容已经实现了上述方案的浏览器,同时加入新的缓存方案,服务器除了告诉浏览器 Expires ,同时告诉浏览器一个相对时间 Cache-Control:max-age=10秒。意思是在10秒以内,使用缓存到浏览器的 a.js 资源。

    浏览器先检查 Cache-Control,如果有,则以 Cache-Control 为准,忽略 Expires。如果没有 Cache-Control,则以 Expires 为准。

    ==============================================================================================================================

    继续改进,增加文件内容对比,引入Etag

    为了解决文件修改时间只能精确到秒带来的问题,我们给服务器引入 Etag 响应头,a.js 内容变了,Etag 才变。内容不变,Etag 不变,可以理解为 Etag 是文件内容的唯一 ID。 同时引入对应的请求头 If-None-Match,每次浏览器请求服务器的时候,都带上If-None-Match字段,该字段的值就是上次请求 a.js 时,服务器返回给浏览器的 Etag。

    • 浏览器请求 a.js。
    • 服务器返回 a.js,同时告诉浏览器过期绝对时间(Expires)以及相对时间(Cache-Control:max-age=10),以及a.js上次修改时间Last-Modified,以及 a.js 的Etag。
    • 10秒内浏览器再次请求 a.js,不再请求服务器,直接使用本地缓存。
    • 11秒时,浏览器再次请求 a.js,请求服务器,带上上次修改时间 If-Modified-Since 和上次的 Etag 值 If-None-Match。
    • 服务器收到浏览器的If-Modified-Since和Etag,发现有If-None-Match,则比较 If-None-Match 和 a.js 的 Etag 值,忽略If-Modified-Since的比较。
    • a.js 文件内容没变化,则Etag和If-None-Match 一致,服务器告诉浏览器继续使用本地缓存(304)。
    • 如此往复。

    =====================================================================================================================

    除此以外的东东

    Cache-Control 除了可以设置 max-age 相对过期时间以外,还可以设置成如下几种值:

    • public,资源允许被中间服务器缓存。

    浏览器请求服务器时,如果缓存时间没到,中间服务器直接返回给浏览器内容,而不必请求源服务器。

    • private,资源不允许被中间代理服务器缓存。

    浏览器请求服务器时,中间服务器都要把浏览器的请求透传给服务器。

    • no-cache,浏览器不做缓存检查。

    每次访问资源,浏览器都要向服务器询问,如果文件没变化,服务器只告诉浏览器继续使用缓存(304)。

    • no-store,浏览器和中间代理服务器都不能缓存资源。

    每次访问资源,浏览器都必须请求服务器,并且,服务器不去检查文件是否变化,而是直接返回完整的资源。

    • must-revalidate,可以缓存,但是使用之前必须先向源服务器确认。
    • proxy-revalidate,要求缓存服务器针对缓存资源向源服务器进行确认。
    • s-maxage:缓存服务器对资源缓存的最大时间。

    Cache-Control 对缓存的控制粒度更细,包括缓存代理服务器的缓存控制。

    文章介绍到此,如有兴趣,可以动手实践下。

    强缓存:

    1.expires

    2.cache-control

    协商缓存:

    1.Last-Modified/If-Modified-Since (在请求头中)

    2.Etag/If-None-Match(在请求头中)

  • 相关阅读:
    泛微云桥e-Bridge 目录遍历,任意文件读取
    (CVE-2020-8209)XenMobile-控制台存在任意文件读取漏洞
    selenium 使用初
    将HTML文件转换为MD文件
    Python对word文档进行操作
    使用java安装jar包出错,提示不是有效的JDK java主目录
    Windows server 2012安装VM tools异常解决办法
    ifconfig 命令,改变主机名,改DNS hosts、关闭selinux firewalld netfilter 、防火墙iptables规则
    iostat iotop 查看硬盘的读写、 free 查看内存的命令 、netstat 命令查看网络、tcpdump 命令
    使用w uptime vmstat top sar nload 等命令查看系统负载
  • 原文地址:https://www.cnblogs.com/eret9616/p/9273399.html
Copyright © 2011-2022 走看看