浏览器 HTTP 协议缓存机制详解--网络缓存决策机制流程图
- 1、缓存的分类
- 2、浏览器缓存机制详解
- 2.1 HTML Meta标签控制缓存
- 2.2 HTTP头信息控制缓存
- 2.2.1 浏览器请求流程
- 2.2.2 几个重要概念解释
- 3、用户行为与缓存
- 4、Refer:
https://www.cnblogs.com/520yang/articles/4807408.html
最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control、为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag,有时又没有带?等等。。。
后来查了一些资料以及同事亲自验证,总算对这些问题有了个清晰的理解,现在整理出来以备忘。
1、缓存的分类
缓存分为服务端侧(server side,比如 Nginx、Apache)和客户端侧(client side,比如 web browser)。
服务端缓存又分为 代理服务器缓存 和 反向代理服务器缓存(也叫网关缓存,比如 Nginx反向代理、Squid等),其实广泛使用的 CDN 也是一种服务端缓存,目的都是让用户的请求走”捷径“,并且都是缓存图片、文件等静态资源。
客户端侧缓存一般指的是浏览器缓存,目的就是加速各种静态资源的访问,想想现在的大型网站,随便一个页面都是一两百个请求,每天 pv 都是亿级别,如果没有缓存,用户体验会急剧下降、同时服务器压力和网络带宽都面临严重的考验。

2、浏览器缓存机制详解
浏览器缓存控制机制有两种:HTML Meta标签 vs. HTTP头信息
2.1 HTML Meta标签控制缓存
浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如: Expires; Cache-control等)。但是也有非HTTP协议定义的缓存机制,如使用HTML Meta 标签,Web开发者可以在HTML页面的<head>节点中加入<meta>标签,代码如下:
|
1
|
<META HTTP-EQUIV="Pragma" CONTENT="no-cache"> |
上述代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。使用上很简单,但只有部分浏览器可以支持,而且所有缓存代理服务器都不支持,因为代理不解析HTML内容本身。而广泛应用的还是 HTTP头信息 来控制缓存,下面我主要介绍HTTP协议定义的缓存机制。
2.2 HTTP头信息控制缓存
2.2.1 浏览器请求流程
- 浏览器第一次请求流程图:

- 浏览器再次请求时:

2.2.2 几个重要概念解释
- Expires策略:Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大(比如时钟不同步,或者跨时区),那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。
- Cache-control策略(重点关注):Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
|
1
2
3
4
5
6
7
8
9
|
值可以是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age各个消息中的指令含义如下:Public指示响应可被任何缓存区缓存。Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。no-cache指示请求或响应消息不能缓存,该选项并不是说可以设置”不缓存“,容易望文生义~no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存,完全不存下來。max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。 |
- Last-Modified/If-Modified-Since:Last-Modified/If-Modified-Since要配合Cache-Control使用。
|
1
2
|
Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。 |
- Etag/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用。
|
1
2
|
Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。 |
- 既生Last-Modified何生Etag?你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
|
1
2
3
|
Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形 |
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag一起使用时,服务器会优先验证ETag。
- yahoo的Yslow法则中则提示谨慎设置Etag:需要注意的是分布式系统里多台机器间文件的last-modified必须保持一致,以免负载均衡到不同机器导致比对失败,Yahoo建议分布式系统尽量关闭掉Etag(每台机器生成的etag都会不一样,因为除了 last-modified、inode 也很难保持一致)。
- Pragma行是为了兼容HTTP1.0,作用与Cache-Control: no-cache是一样的。
- 最后总结下几种状态码的区别:

3、用户行为与缓存
浏览器缓存行为还有用户的行为有关,如果大家对 强制刷新(Ctrl + F5) 还有印象的话应该能立刻明白我的意思~
|
用户操作 |
Expires/Cache-Control |
Last-Modified/Etag |
|
地址栏回车 |
有效 |
有效 |
|
页面链接跳转 |
有效 |
有效 |
|
新开窗口 |
有效 |
有效 |
|
前进、后退 |
有效 |
有效 |
|
F5刷新 |
无效(BR重置max-age=0) |
有效 |
|
Ctrl+F5刷新 |
无效(重置CC=no-cache) |
无效(请求头丢弃该选项) |
具体请参考文末 Refer [6]
4、Refer:
[1] 浏览器缓存机制
http://www.cnblogs.com/skynet/archive/2012/11/28/2792503.html
[2] Web 开发人员需知的 Web 缓存知识
http://www.oschina.net/news/41397/web-cache-knowledge
[3] 浏览器缓存详解:expires,cache-control,last-modified,etag详细说明
http://blog.csdn.net/eroswang/article/details/8302191
[4] 在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别
http://cloudbbs.org/forum.php?mod=viewthread&tid=15790
http://blog.csdn.net/yui/article/details/6584401
[5] Cache Control 與 ETag
https://blog.othree.net/log/2012/12/22/cache-control-and-etag/
[6] 缓存的故事
http://segmentfault.com/blog/animabear/1190000000375344
[7] Google的PageSpeed网站优化理论中提到使用Etag可以减少服务器负担
https://developers.google.com/speed/docs/pss/AddEtags
[8] yahoo的Yslow法则中则提示谨慎设置Etag
浏览器 HTTP 协议缓存机制详解--网络缓存决策机制流程图的更多相关文章
- iOS的消息转发机制详解
iOS开发过程中,有一类的错误会经常遇到,就是找不到所调用的方法,当然这类问题比较好解决,给当前对象或其父类对象添加该方法即可,使得编译器在编译时能正确找到该方法:或者,还有另外的方法,由于Objec ...
- 浏览器 HTTP 协议缓存机制详解
最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control.为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag, ...
- nginx平台初识(二) 浏览器 HTTP 协议缓存机制详解
1.缓存的分类 缓存分为服务端侧(server side,比如 Nginx.Apache)和客户端侧(client side,比如 web browser). 服务端缓存又分为 代理服务器缓存 和 反 ...
- (转载)详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表
郑重声明:原文转载于http://dengqi.blog.51cto.com/5685776/1223132 向好文章致敬!!! 一:MAC地址表详解 说到MAC地址表,就不得不说一下交换机的工作原理 ...
- 详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dengqi.blog.51cto.com/5685776/1223132 一:M ...
- PHP缓存机制详解
一,PHP缓存机制详解 我们可以使用PHP自带的缓存机制来完成页面静态化,但是仅靠PHP自身的缓存机制并不能完美的解决页面静态化,往往需要和其他静态化技术(通常是伪静态技术)结合使用. output ...
- 二,PHP缓存机制详解
一,PHP缓存机制详解 我们可以使用PHP自带的缓存机制来完成页面静态化,但是仅靠PHP自身的缓存机制并不能完美的解决页面静态化,往往需要和其他静态化技术(通常是伪静态技术)结合使用. output ...
- [转载]详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表
[转载]详解网络传输中的三张表,MAC地址表.ARP缓存表以及路由表 虽然学过了计算机网络,但是这部分还是有点乱.正好在网上看到了一篇文章,讲的很透彻,转载过来康康. 本文出自 "邓奇的Bl ...
- hibernate缓存机制详解
hiberante面试题—hibernate缓存机制详解 这是面试中经常问到的一个问题,可以按照我的思路回答,准你回答得很完美.首先说下Hibernate缓存的作用(即为什么要用缓存机制),然后再 ...
随机推荐
- Caused by: android.os.TransactionTooLargeException总结
错误信息 Error: android.os.TransactionTooLargeException W/ActivityManager(344): android.os.TransactionTo ...
- MySQL下做Master/Slave同步,延迟太大怎么办?
slave的延迟是比较常见的,如果短暂的延迟后还能追上,一般就能接受了. 用innodb不是坏事,会减少一些slave中止的情况.如果是myisam的表,insert update delete操 ...
- 暑假集训D20总结
刷题 今天是瞎XX切题的一天 我要是不写题解的话,我自己都不知道刷了多少专题 数学什么的= = 生活 也就那样吧,没啥特别的 这两天倒是特别鬼畜 先是我点了一下某喵的$cena$,然后他的$cena$ ...
- CodeForces - 284C - Cows and Sequence
先上题目: C. Cows and Sequence time limit per test 3 seconds memory limit per test 256 megabytes input s ...
- [bzoj3702/2212][Poi2011]二叉树/Tree Rotations_线段树
二叉树 Tree Rotations bzoj-3702 bzoj-2212 Poi-2011 题目大意:现在有一棵二叉树,所有非叶子节点都有两个孩子.在每个叶子节点上有一个权值(有n个叶子节点,满足 ...
- ZooKeeper官方文档资源
一般来说官方的文档是最权威的. 入口:http://zookeeper.apache.org/ 在右侧即可进入相应版本文档: 如果想要看主干的文章,入口如下,主干是最稳当的版本:http://zook ...
- 全部对于Unity3D中 NGUI 触发事件的监听方法
NGUI事件的种类非常多.比方点击.双击.拖动.滑动等等,他们处理事件的原理差点儿万全一样,本文仅仅用button来举例. 方法一.直接监听事件 把以下脚本直接绑定在button上.当button点击 ...
- 大规模的I/O流中有效识别大数据并增强时间局部性
一篇热数据识别存储外文翻译,本文主要在讲思想 原文题目: HDCat: Effectively Identifying Hot Data in Large-scale I/O Streams ...
- 学界| UC Berkeley提出新型分布式框架Ray:实时动态学习的开端—— AI 应用的系统需求:支持(a)异质、并行计算,(b)动态任务图,(c)高吞吐量和低延迟的调度,以及(d)透明的容错性。
学界| UC Berkeley提出新型分布式框架Ray:实时动态学习的开端 from:https://baijia.baidu.com/s?id=1587367874517247282&wfr ...
- Codeforces--598A--Tricky Sum(数学)
Tricky Sum Tricky SumCrawling in process... Crawling failed Time Limit:1000MS Memory Limit:26 ...