• http学习之路--缓存机制--Mr.Ember


    http学习之路
     
    摘要
     
    在请求的页面里有些静态文件(图片,css,js)不是经常变化的,将这些文件存储起来,也是客户端优化用户浏览体验的一个好方法。http缓存作为web性能优化的重要手段,但是对于前端来说只是知道浏览器会对静态文件进行缓存,但为什么被缓存,缓存是怎么失效的并不清楚。下面为大家介绍http的缓存机制。
     
    http缓存分类
    缓存分为强制缓存协商缓存,强制缓存在缓存数据未失效情况下,不需要和服务器进行交互。而协商缓存需要进行和服务器进行比较和判断是否进行缓存。
    两种缓存同时存在的情况下,强制缓存优先于协商缓存。
     
    强制缓存
     
    1. Expires
    expires的值是告诉浏览器的缓存过期时间(值为GMT时间,即格林尼治时间),即下次请求时,没有到达过期时间,浏览器会直接使用缓存数据。
     
    虽然这种方式添加了缓存控制,节省了流量,但还是存在很多问题
            (1) 由于客户端时间是服务器没办法控制的时间,假如用户改变了客户端时间,就可能造成一些缓存的更新不及时
            (2) 缓存过期后,不管文件有咩有发生变化,浏览器都会重新请求服务器
     
    2. Catch-Control

    针对以上浏览器和服务器时间不一致问题,加入了新的缓存方案,服务器不直接告诉浏览器过期时间,而是告诉浏览器一个相对时间Cache-Control=10秒,意思是10秒内,直接使用浏览器缓存。

     
     
    协商缓存
    强制缓存的弊端很明显,都是通过时间判断是否请求服务器加载,但是如果文件没有发生变化,就会造成浪费服务器的资源。
    协商缓存有两组报文结合使用

     
    Last-modified

    为了节省服务器资源,再次改变方案。浏览器和服务器协商,服务器每次返回文件时,都会告诉浏览器文件在服务器上最近修改的时间,请求的过程如下:

     

    1. 浏览器请求静态资源Demo.png
    2. 服务器读取磁盘,返回给浏览器文件,并带上文件上次修改时间Last-Modified(GMT标准格式)
    3. 当浏览器缓存文件过期时,浏览器会带上If-Modified-since(等于上次请求的last-modified)请求服务器。
    4. 服务器比较请求头里的If-modified-since和文件上次修改的时间,如果文件一致就继续使用浏览器的缓存(304),不一致就重新请求服务器并返回last-modified
    5. 循环请求。。。。
     
    虽然这个方式比上面三个方式都有进一步的优化,浏览器检测文件是否有变化,如果没有变化,就直接使用缓存文件还是有些问题:
    1. last-modified是使用(GMT)时间,只能精确到秒,如果文件在一秒之内改变很多次,浏览器就没办法去识别并请求新的文件。
    2. 如果文件经过多次修改,但是内容没有变化,服务器需要重新返回请求文件。
     
    Etag

    为了解决文件修改时间不精确的问题,浏览器再和服务器进行协商,这次不返回时间,返回文件唯一标识Etag,只有当文件内容改变时,Etag才会改变。请求过程如下:

     

    1. 浏览器请求静态资源demo.png
    2. 服务器读取磁盘,把demo.png文件返回给浏览器,并带上文件的唯一标识Etag
    3. 当浏览器的缓存文件过期时,浏览器带上If-None-Match(等于上次上次的Etag)再次请求服务器
    4. 服务器比较请求头的If-None_Match和文件的Etag,如果一致就继续使用缓存文件(304),不一致带上Etag重新请求服务器。
    5. 循环请求。。。
     
     
     
    关于Pragma
     
    当该字段值为no-cache的时候,会告诉浏览器不要对该资源缓存,即每次都得向服务器发一次请求才行。
    res.setHeader('Pragma', 'no-cache') //禁止缓存
    res.setHeader('Cache-Control', 'public,max-age=120') //2分钟复制代码
      通过Pragma来禁止缓存,通过Cache-Control设置两分钟缓存,但是重新访问我们会发现浏览器会再次发起一次请求,说明了Pragma的优先级高于Cache-Control
     
    关于Cache-Control
     
    我们看到Cache-Control中有一个属性是public,那么这代表了什么意思呢?其实Cache-Control不光有max-age,它常见的取值private、public、no-cache、max-age,no-store,默认值为private,各个取值的含义如下:
    • private: 客户端可以缓存
    • public: 客户端和代理服务器都可缓存
    • max-age=xxx: 缓存的内容将在 xxx 秒后失效
    • no-cache: 需要使用对比缓存来验证缓存数据
    • no-store: 所有内容都不会缓存,强制缓存,对比缓存都不会触发
      所以我们在刷新页面的时候,如果只按F5只是单纯的发送请求,按Ctrl+F5会发现请求头上多了两个字段Pragma: no-cache和Cache-Control: no-cache。
     
    缓存的优先级
     
      上面我们说过强制缓存的优先级高于协商缓存,Pragma的优先级高于Cache-Control,那么其他缓存的优先级顺序怎么样呢?网上查阅了资料得出以下顺序(PS:有兴趣的童鞋可以验证一下正确性告诉我):
    Pragma > Cache-Control > Expires > ETag > Last-Modified
     
  • 相关阅读:
    AFO以后的机房游记
    THUSC2019 退役记
    最小树形图模板
    Codeforces Round #618 (Div. 2)
    「CF662C」 Binary Table
    「SCOI2012」喵星球上的点名
    P4480 「BJWC2018」「网络流与线性规划24题」餐巾计划问题
    CSP-S 2019 游记
    「BZOJ2839」集合计数
    「SPOJ 3105」Power Modulo Inverted
  • 原文地址:https://www.cnblogs.com/teteWang-Ember/p/10323074.html
Copyright © 2020-2023  润新知