HTTP缓存与Chrome浏览器的缓存协作 研究

前言

网页与网页资源的缓存是浏览器与服务器端共同协作完成的。主要参与者 Cache-Control、Etag、LastModified三者。
标准文档:https://www.rfc-editor.org/rfc/rfc9111#name-cache-control

一、Cache-Control

Cache-Control扮演着缓存最主要的角色,Etag与LastModified是协商缓存的主要角色。

1. 取值为no-store

当响应头中有Cache-Control=no-store的时候。浏览器不会使用任何缓存,也不会有任何协商缓存参与(etag与LastModified).

2. 取值为no-cache

Cache-Control为no-cache的时候会先去进行协商缓存即通过etag或者LastMdoified进行验证本地的缓存是否有效。当服务端验证后告诉浏览器你那边的缓存可以用(即返回304)或者不可以(返回200状态并返回对应的内容)。注意Cache-Control为maxage=0时与no-cache效果相同,区别在于no-cache在http1.0中不支持,为了向下兼容会同时使用max-age=0。

3. 取值为must-revalidate

Cache-Control为must-revalidate时,会在使用缓存前进行缓存验证,验证方式与no-cache有所不同。no-cache永远都会使用协商缓存。但是must-revalidate会由浏览器自身新鲜度检测策略来定。对于html文件来说会一直使用协商缓存,但是对于js,css,img对象就不一样,如果在短时间内再次访问该资源一般会从memory-cache或者diskcache中获取,有时候又会通过协商缓存。

4. 取值为max-age > 0s 单位秒

Cache-Control为max-age > 0 。所有资源都会缓存到指定秒数之前,在缓存期间原则上永远也不会访问服务器。注意我加了一个“原则上”。点击刷新按钮/f5/ctrl+R会跳过强缓存,直接走协商缓存。地址栏回车/页面链接跳转/打开新窗口/标签页/history前进后退会首先使用强缓存。

二、Etag

Etag时通过为文件计算一个指纹值,返回给浏览器,浏览器记住这个指纹。当使用浏览器进行缓存验证是,会发送请求头 If-None-Match=指纹(If-None-Match顾名思义如果指纹不匹配你就给我返回新的数据),服务端发现请求头中存在If-None-Match就会去匹配新的指纹,如果相等则范围304否则范围200和数据内容

三、LastModified

LastModifed顾名思义是通过文件的最后修改时间来校验缓存。浏览器进行缓存校验是,会发送请求头
If-Modified-Since=最后修改时间(顾名思义如果文件的修改时间大于了我发送给你的时间,你服务器就必须返回新数据给我),服务器发现请求头中存在If-Modified-Since则会去使用修改时间去对比发现在给定时间之后修改我就返回新数据给浏览器否则返回304。

据我猜测如果同时存在If-Modified-Since和If-None-Match头浏览器应该优先使用If-None-Match。

四、请求头中的一些特殊值(Request Header中的Cache-Control)

以下值只能放到请求头中

1. Cache-Control=max-stale

它表示就是缓存过期了,如果过期时间还在max-stale内,则还是使用缓存。https://www.rfc-editor.org/rfc/rfc9111#name-max-stale

2. Cache-Control=min-fresh

Cache-Control=min-fresh 与 max-stale相似。nax-stale相当于扩大max-age而min-fresh相当于缩小max-age范围。例如:max-age=600如果设置min-fresh=60则缓存时间已过540s后将不使用缓存

3. Cache-Control=only-if-cached

only-if-cached 表示有缓存并且未过期则使用缓存否则就返回状态码(504 Gateway Timeout)。此值目前只有firefox浏览器支持https://caniuse.com/?search=only-if-cached,虽然caniuse中显示firefox支持,但是我测试后发现没有缓存的情况也不会返回504.

五、 计算启发式新鲜度

如果响应中未显示指定缓存过期时间、浏览器便使用计算启发式新鲜度的方式进行处理缓存,换句话说就是如果服务未告诉我如何缓存我就使用“计算启发式新鲜度”这种方式来处理缓存。但必须满足响应是可缓存的,条件如下:

  1. 状态代码被定义为“启发式可缓存” ,状态码文档中15.1中说明了:

    具有被定义为启发式可缓存的状态代码(例如,本规范中的 200、203、204、206、300、301、308、404、405、410、414 和 501)的响应可以由具有启发式过期的缓存重用除非方法定义或显式缓存控制 [ CACHING ]另有指示;所有其他状态代码都不可启发式缓存。

  2. 响应被标记为可缓存的(例如,使用公共响应指令 Cache-Control=public)

具体算法:如果响应具有 Last-Modified 标头字段([ HTTP ]的第 8.8.2 节),则鼓励缓存使用启发式过期值,该值不超过自该时间以来间隔的一部分。该分数的典型设置可能是 10%。(注:这个算法并不是绝对的,不同浏览器可能不同,并且这个过期值可能并不是单层的按照上面方式进行计算、可能会考虑各种因素)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值