http学习笔记——浏览器缓存机制

前言

作为前端开发,我们在web开发的过程中需要调用后端接口,用node搭建服务器或者写一些中间件对数据进行封装处理等等,必不可少地会和http打上交道,所以我们都要掌握http各方面的知识。

说到性能优化问题,一定会提到http缓存,如何利用好http缓存机制,理解http缓存的整个过程和http如何设置缓存,把这些都弄懂后会对我们以后在项目实践中都会有很大帮助。本篇文章将会和大家分享一下笔者对http缓存机制的一些知识整理和总结。

与缓存相关的http头部字段

我们先看看http头部中与缓存相关的一些字段的基本概念和用法。

Pragma

该字段来自http1.0时代,当其设置为no-cache的时候和Cache-Control: no-cache效果一样,意为无缓存,客户端不会读取缓存,直接向服务器发起请求。因为是http1.0留下的遗物,仅为了做向后的兼容。

pragma

Expires

该字段也是来自http1.0时代,用于控制缓存时间。例如设置了Thu, 18 Jul 2019 08:43:30 GMT,即告诉浏览器如果没有超过这个时间,将不会向服务器发起请求。

Expires存在两个缺点:

  1. Expires的值是一个时间值。这就要求了客户端和服务器端需要时间严格同步。否就会导致缓存失效。
  2. 当Expires定义的时间过期了,服务器需要重新配置一个新的时间。
expires

cache-control

http1.1新增了 Cache-Control 字段,用来定义缓存过期时间,若报文中同时出现了 Pragma、Expires 和 Cache-Control,会以 Cache-Control 为准。(网上也有Pragma优先级高于Cache-Control的说法,但是一般设置了Pragma: no-cache的话也会设置Cache-Control: no-cache的吧-.-)

先看看cache-control的常用设置值

cache-directive 描述
no-cache 不使用缓存,强制向服务器请求资源
no-store 所有内容都不会被缓存
public 资源将会被客户端和代理服务器缓存
private 资源将会被客户端缓存但不会被代理服务器缓存
max-age 缓存资源的最大时间段
s-maxage 同上, 依赖public设置, 覆盖max-age, 且只在代理服务器上有效.
max-stale 指定时间内, 即使缓存过时, 资源依然有效
min-fresh 缓存的资源至少要保持指定时间的新鲜期
must-revalidation / proxy-revalidation 作用与no-cache类似,强制重新向服务器(或代理)发起验证
only-if-cached 只从缓存中获取资源,若没有缓存则返回504
cachecontrol1

cache-control字段可以包含以上多个值,但是最终会选择最为保守的方案。

cachecontrol2

Last-Modified & If-Modified-Since & If-Unmodified-Since

当客户端第一次发起请求时,服务端会返回状态码200以及客户端请求的资源,同时响应头部会带有Last-Modified字段,标记此文件在服务器最后修改的时间。

last-modified

而下次客户端再次发起请求的时候,请求头部就会带有If-Modified-Since或者If-Unmodified-Since的字段,他们的值是上一次响应头部Last-Modified字段的值,用于校验资源是否过期。

若使用If-Modified-Since则服务端会判断此时间后此文件是否修改过,如果没有修改过则使用缓存资源,返回304,否则将获取资源返回200.

若使用If-Unmodified-Since,则是相反的情况,若资源未修改过则获取资源,否则返回412(Precondition Failed)响应。它常用于两个场景:

  1. 不安全的请求, 比如说使用post请求更新wiki文档, 文档未修改时才执行更新
  2. 与 If-Range 字段同时使用时, 可以用来保证新的片段请求来自一个未修改的文档

当遇到下面情况时,If-Unmodified-Since 字段会被忽略:

  1. Last-Modified值对上了(资源在服务端没有新的修改)
  2. 服务端需返回2XX和412之外的状态码
  3. 传来的指定日期不合法

Last-Modified存在的问题

  1. 服务器端的静态资源通常需要编译打包, 可能出现资源内容没有改变, 而Last-Modified却改变的情况.
  2. 某些文件修改非常频繁,比如在秒以下的时间内进行修改,If-Modified-Since无法检查到。
  3. 某些服务器不能精确的得到文件的最后修改时间。

Etag & If-Match & If-None-Match

为了解决以上Last-Modified存在的问题,http1.1还提出另外一个字段——Etag。Etag,实体首部字段,服务器资源的唯一标识符, 客户端可以根据ETag值缓存数据, 节省带宽。因此Etag的优先级高于Last-Modified。

服务器会通过某种算法,给资源计算得出一个唯一标志符(比如md5标志),在把资源响应给客户端的时候,会在实体首部加上“ETag: 唯一标识符”一起返回给客户端。

etag

当再次向服务器发起请求时,请求头部会发送If-Match或者If-None-Match字段,服务器收到请求后则将其与被请求资源的唯一标识进行比对。

If-None-Match,若不同,说明资源又被改动过,则响应整片资源内容,返回状态码200;若相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

If-Match,若不同,则返回412(Precondition Failed) 状态码给客户端。否则服务器直接忽略该字段。其应用场景是客户端走PUT方法向服务端请求上传/更替资源,这时候可以通过 If-Match 传递资源的ETag。

使用Etag注意两点:

  1. 如果资源是走分布式服务器(比如CDN)存储的情况,需要这些服务器上计算ETag唯一值的算法保持一致,才不会导致明明同一个文件,在服务器A和服务器B上生成的ETag却不一样。
  2. 如果 Last-Modified 和 ETag 同时被使用,则要求它们的验证都必须通过才会返回304,若其中某个验证没通过,则服务器会按常规返回资源实体及200状态码。

http缓存策略

做好前期的知识铺垫,马上扔个流程图上来

http

我们看到图中不同阶段有不同的缓存策略,我们逐一看看。

过期策略(命中强缓存)

过期策略主要是通过Expires和CacheControl来判断缓存是否已经过期,若两者都没有设置的话,则使用浏览器默认的一套‘10%’算法来进行判断,通常会取响应头的Date_value - Last-Modified_value值的10%作为缓存时间。

假如缓存没有过期则不向浏览器发出请求了,但是抓包的时候还是返回200 ok,但是留意了,会有Provisional headers are shown 的提示,说明就是浏览器并未发出请求, 缓存依然有效。

guoqi

(这坑很大啊,明明没有向浏览器发起请求,还显示200来吓唬人-.-)

这时在Chrome里面会出现200(from disk cache)和200(from memory cache)的情况。官方解释如下:

Chrome employs two caches — an on-disk cache and a very fast in-memory cache. The lifetime of an in-memory cache is attached to the lifetime of a render process, which roughly corresponds to a tab. Requests that are answered from the in-memory cache are invisible to the web request API. If a request handler changes its behavior (for example, the behavior according to which requests are blocked), a simple page refresh might not respect this changed behavior. To make sure the behavior change goes through, call handlerBehaviorChanged() to flush the in-memory cache. But don't do it often; flushing the cache is a very expensive operation. You don't need to call handlerBehaviorChanged() after registering or unregistering an event listener.

意思大概就是Chrome会使用磁盘缓存和内存缓存,内存缓存是直接从内存中读取的,所以速度更快。内部具体的规则还不大了解,估计是根据渲染刷新方式和文件大小决定的。

假如缓存过期了则走下一步协商策略。

协商策略

协商策略是通过Last-Modified和Etag字段向服务器发起验证能否使用缓存资源,若验证通过,则返回304状态码,根据响应头更新缓存,使用缓存资源。

xieshang

若没有通过校验,则向服务器获取资源,返回200,并将响应内容存进缓存。

存储策略

这没啥好说的,就是将响应内容存入缓存或者根据响应内容更新缓存。

综上,再看回这个流程图,我们梳理一下整个过程。

  1. 客户端首次发起请求,没有缓存数据,向服务器请求数据,服务器返回数据和缓存规则,并存入缓存。
  2. 客户端再次发起请求,检测是否有缓存,若有缓存,则检测缓存是否过期,若缓存没有过期,则使用缓存数据。(过期策略)
  3. 若缓存数据已过期,则向服务器发起校验,验证缓存是否有效,若通过验证,则使用缓存,返回304;反之向服务器发起请求,返回200。(协商策略)

参考文章

浏览器缓存控制

浏览器缓存机制剖析

http缓存浅谈

彻底弄懂HTTP缓存机制及原理

HTTP缓存控制小结

你应该知道的浏览器缓存知识

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容

  • 浏览器对于请求资源, 流程如图所示: 可以看到浏览器的缓存机制分为两个部分: 1、当前缓存是否过期? 2、服务器中...
    zhoulujun阅读 1,170评论 0 3
  • 浅谈浏览器Http的缓存机制 ✦ ✦ ✦ ✦ ✦ ✦ ✦ ✦ 针对浏览器的http缓存的分析也算是老生常谈了,每隔...
    meng_philip123阅读 998评论 0 10
  • 针对浏览器的http缓存的分析也算是老生常谈了,每隔一段时间就会冒出一篇不错的文章,其原理也是各大公司面试时几乎必...
    全端玩法阅读 873评论 0 9
  • 针对浏览器的http缓存的分析也算是老生常谈了,每隔一段时间就会冒出一篇不错的文章,其原理也是各大公司面试时几乎必...
    单纯的土豆阅读 379评论 0 2
  • 文/猎头王 来自不同的方向 汇入总流的同时 并在一起 你搭出你的桨,说 这是我的生命 我伸出我的橹,说 这是我的真...
    纽森猎头王凡阅读 265评论 2 1