【HTTP缓存】浏览器缓存理论知识
时间:2016-12-12 17:51:30
作者: zhongxia
零、前言
这里主要写的是理论,具体实践的比较少,后期写一个实践教程,内容基本都是从参考文章里面抄过来的【看完文章,顺便写做下笔记,加深理解。】
浏览器缓存,也就是客户端缓存,既是网页性能优化里面静态资源相关优化的一大利器,也是无数web开发人员在工作过程不可避免的一大问题,所以在产品开发的时候我们总是想办法避免缓存产生,而在产品发布之时又在想策略管理缓存提升网页的访问速度。
了解浏览器的缓存命中原理,是开发web应用的基础,本文着眼于此,学习浏览器缓存的相关知识,总结缓存避免和缓存管理的方法,结合具体的场景说明缓存的相关问题。希望能对有需要的人有所帮助。
一、浏览器缓存基本认识
1. 强缓存 和 协商缓存
浏览器在加载资源的时,先根据 http header 判断它是否命中强缓存.
命中强缓存:浏览器直接从自己缓存中读取资源,不发送请求到服务器
不命中强缓存:浏览器发送一个请求到服务器,服务器根据资源的另外一些 http header 验证 该资源 是否命中 协商缓存
命中协商缓存:将请求返回,但不是返回该资源的数据,而是告诉浏览器可以直接从缓存中加载这个资源。
不命中协商缓存:服务器返回该资源数据
2. 异同点 和 关系
共同点:命中,都是从浏览器缓存中加载资源
不同点:强缓存不发送请求到服务器,协商缓存会发送请求。
必须开启强缓存,协商缓存才会起作用
二、强缓存原理
什么是协商缓存?
如图,返回http状态为200,size为 form cache 的就是强缓存
1. HTTP Response Header 看强缓存
Expires
HTTP1.0 时代,Expires 【表示资源过期时间】【缓存过期的下一个时间 必须GMT 格式】
可能存在问题:服务器时间和客户端时间不一致,因此 HTTP1.1 出了一些 Cache-control
如图:
Cache-control
HTTP1.1 时代,Cache-control: 过期时间【缓存多少毫秒】
如图:
例子:
Expires步骤
浏览器第一次请求资源,服务器在返回的同时,会在 response 的 header 上加上 Expires
浏览器收到资源后,把资源和 Expires 一起缓存下来
第二次请求资源时,拿出Expires和当前请求时间比较下,如果还未过期,则直接从缓存中读取出来,【这个就叫命中缓存】
没有命中的话,去服务端请求,走协商缓存道路,最后返回时,会返回一个新的 Expires , 浏览器在缓存下来。
Cache-control 步骤
和 Expires一样,只是 过期时间=当前时间+Cache-control 的 Max-age 缓存毫秒数
Cache-control 和 Expires
- 这两个可以一起用,也可以只用其中一个 【一起用,优先级: Cache-Control > Expires】
- Expires 是比较老的强缓存管理Header,因为它是绝对时间,而服务器时间和客户端时间相差大,或者修改客户端时间,就会影响缓存命中率
- Cache-control 是相对时间,受到的影响小一些
如何设置强缓存?
1. 代码形式
通过代码的形式,在web服务器的返回响应 header 中添加 Expies, Cache-control
java.util.Date date = new java.util.Date();
response.setDateHeader("Expires",date.getTime()+20000); //Expires:过时期限值
response.setHeader("Cache-Control", "public"); //Cache-Control来控制页面的缓存与否,public:浏览器和缓存服务器都可以缓存页面信息;
response.setHeader("Pragma", "Pragma"); //Pragma:设置页面是否缓存,为Pragma则缓存,no-cache则不缓存
设置不缓存
response.setHeader( "Pragma", "no-cache" );
response.setDateHeader("Expires", 0);
response.addHeader( "Cache-Control", "no-cache" );//浏览器和缓存服务器都不应该缓存页面信息
2. web服务器配置
让web服务器在响应资源的时候统一添加Expires和Cache-Control Header
nginx和apache作为专业的web服务器,都有专门的配置文件,可以配置expires和cache-control,这方面的知识,如果你对运维感兴趣的话,可以在百度上搜索“nginx 设置 expires cache-control”或“apache 设置 expires cache-control”都能找到不少相关的文章。
3. 强缓存的应用
强缓存是前端性能优化最有力的工具,没有之一。
大量的静态资源网站,一定要利用强缓存,提高响应速度
例子,京东页面,强缓存到2026年。【这个强缓存可以有】
使用强缓存后,如何更新网站呢?
给文件加上 hash 值。
知乎上的完美解决方案
https://www.zhihu.com/question/20790576
- 注意点【强缓存针对静态资源,动态资源不要,html资源不要。】
强缓存还有一点需要注意的是,通常都是针对静态资源使用,动态资源需要慎用,除了服务端页面可以看作动态资源外,那些引用静态资源的html也可以看作是动态资源,如果这种html也被缓存,当这些html更新之后,可能就没有机制能够通知浏览器这些html有更新,尤其是前后端分离的应用里,页面都是纯html页面,每个访问地址可能都是直接访问html页面,这些页面通常不加强缓存,以保证浏览器访问这些页面时始终请求服务器最新的资源
三、协商缓存
1. 什么是协商缓存?
如图:返回http状态304,Not Modified
说白了就是浏览器自己不确定,没有办法决定,因此要找 服务器商量下。 服务器说可以,那浏览器就直接从自己缓存里面找出资源, 服务器说你这个不行啊,过期了。 我给你个新的,浏览器就拿新的咯。
协商缓存要发请求,所有header都是 response 和 request 一人一个。
2. 协商缓存如何控制?
协商缓存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】这两对Header来管理的。
Response Header : Last-Modified, ETag
Request Header : If-Modified-Since , If-None-Match
3. 【Last-Modified,If-Modified-Since】缓存管理方式
第一次跟web服务器请求资源时,在 response 的 header 加上 Last-Modified【文件最后修改时间】
浏览器收到资源的时候,把资源文件和 Last-Modified 缓存起来
再次请求的时候, 在 Request Header 加上 If-Modified-Since 的 header, 这个值,就是 第一次web服务器返回的 Last-Modified。
web服务器收到之后,判断 Last-Modified-Since 和 Last-Modified 是否一致,一致则返回 304 Not Modified. 让浏览器去加载缓存里面的。
不一致的话,返回资源,并返回一个新的 Last-Modified
浏览器继续缓存下来, 然后继续上面的步骤。
【Last-Modified,If-Modified-Since】都是根据服务器时间返回的header,一般来说,在没有调整服务器时间和篡改客户端缓存的情况下,这两个header配合起来管理协商缓存是非常可靠的,但是有时候也会服务器上资源其实有变化,但是最后修改时间却没有变化的情况,而这种问题又很不容易被定位出来,而当这种情况出现的时候,就会影响协商缓存的可靠性。所以就有了另外一对header来管理协商缓存,这对header就是【ETag、If-None-Match】。
4.【ETag、If-None-Match】的缓存管理的方式是
所有的步骤都是差不多的
发送请求,返回资源的时候,也返回了一个 ETag【文件的Hash值】
浏览器缓存资源,并缓存下 ETag
再次请求的时候,Request Header If-None-Match 把上次传过来的 ETag 传过去
web服务器,在生成一个资源文件的 ETag, 然后跟传过来的比较
一样,返回 304 Not-Modified,浏览器从缓存拿
不一样, web服务器返回资源,并返回一个新的 ETag, 然后重复上面操作。
强缓存 和 协商缓存的 缓存管理都是一样的步骤哈。
5. 注意ETag的使用
在分布式部署的时候,多台机器的 Last-Modified 必须保持一致,否则协商缓存会出问题。
分布式部署,不同的机器生成的 ETag 都会不一样。 然后协商缓存就会出问题。【因此如果没有搞定ETag 一致,就先关闭掉。】
协商缓存 需要 配合 强缓存使用 【不启动强缓存,协商缓存也就不起作用】
response header 包含了强缓存的管理 header
四、浏览器行为对缓存的影响
如果资源已经被浏览器缓存下来,在缓存失效之前,再次请求时,默认会先检查是否命中强缓存,如果强缓存命中则直接读取缓存,如果强缓存没有命中则发请求到服务器检查是否命中协商缓存,如果协商缓存命中,则告诉浏览器还是可以从缓存读取,否则才从服务器返回最新的资源。这是默认的处理方式,这个方式可能被浏览器的行为改变:
- 当ctrl+f5强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存;
- 当f5刷新网页时,跳过强缓存,但是会检查协商缓存;
五、注意点
勾选这个 disable cache 缓存, 则不会使用缓存
参考文章
【HTTP缓存】浏览器缓存理论知识的更多相关文章
- 理解web缓存 浏览器缓存
为了: 控制缓存 遇到的现象: 1.开发的时候,浏览器会缓存你的文件,使得你的改动是无效的! 开发过程中:我们是不希望有缓存的. 但正是发布以后,我们是希望页面能够在浏览器缓存,这样用户的体验就会提高 ...
- js清除浏览器缓存的几种方法
2014年9月24日 4692次浏览 关于浏览器缓存 浏览器缓存,有时候我们需要他,因为他可以提高网站性能和浏览器速度,提高网站性能.但是有时候我们又不得不清除缓存,因为缓存可能误事,出现一些错误的数 ...
- Java缓存学习之二:浏览器缓存机制
浏览器端的九种缓存机制介绍 浏览器缓存是浏览器端保存数据用于快速读取或避免重复资源请求的优化机制,有效的缓存使用可以避免重复的网络请求和浏览器快速地读取本地数据,整体上加速网页展示给用户.浏览器端缓存 ...
- 浏览器缓存机制<转>
转这篇文章是感觉可以在图片加载的时候,也使用这样的缓存策略 作者:吴秦出处:http://www.cnblogs.com/skynet/本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或 ...
- 页面加载异常 清除浏览器静态文件 js css 缓存 js动态加载js css文件,可以配置文件后辍,防止浏览器缓存
js清除浏览器缓存的几种方法 - 兔老霸夏 - 博客园 https://www.cnblogs.com/Mr-Rocker/p/6031096.html js清除浏览器缓存的几种方法 一.CSS和 ...
- host缓存,浏览器缓存---解决host缓存带来的伤
1.缓存 缓存,对应工程师来讲简直太熟悉了,太方便了,省略到资源或数据的获取方式,直接缓存到离用户访问最快的地方,也降低服务器的压力,比如: (1)静态文件获取 服务器->cdn->本地磁 ...
- 浏览器缓存_HTTP强缓存和协商缓存
浏览器缓存 浏览器缓存是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档. 所以根据上面的特点,浏览器缓存有下面的优点: 减少冗余的数据传 ...
- 说说web缓存-强缓存、协商缓存
网上关于WEB缓存的文章很多,今天汇总一下. 为什么要用缓存 一般针对静态资源如CSS,JS,图片等使用缓存,原因如下: 请求更快:通过将内容缓存在本地浏览器或距离最近的缓存服务器(如CDN),在不影 ...
- 详解浏览器缓存机制与Apache设置缓存
一.详解浏览器缓存机制 对于,如何说明缓存机制,在网络上找到了两张图,个人认为思路是比较清晰的.总结时,上图. 这里需要注意的有两点: 1.Last-Modified.Etag是响应头里的数据 2.I ...
随机推荐
- SpringMVC redirect中文乱码问题
在使用"redirect:xxx.do?param=中文"时会出现乱码问题,解决方案如下: 使用model.addAttribute来替代直接拼接参数.如下: @RequestMa ...
- Linux给命令设置别名
查看命令别名:alias alias 设置命令别名:alias 别名='命令' alias ll='ls -l' 取消命令别名:unalias 别名 unalias ll 命令永久生效 上面直接在sh ...
- Java 在 CMD 环境下编译
1. 未引用第三方 Jar 包类(该 Java 类默认无包名) # 定位到类存放地址 cd E:\tsgg # 编译命令 javac Test.java # 执行命令 java Test 2. 引用第 ...
- Java技术开发中的坑
1.(2014/05/28)struts2中使用eclipse自动获取getter和setter方法的坑 今天着实被eclipse坑了一把,平时遇到get和set方法时,我都是通过eclipse自动生 ...
- 命令查看当前电脑安装所有版本.NET Core SKD
dotnet --version 查看当前使用版本 dotnet --info 安装的所有版本 包括版本地址 也可用命令帮助 dotnet help
- Java容器类源码分析前言之集合框架结构(基于JDK8)
一.基本概念 Java容器类库的用途是"保存对象",容器库类分为两个不同的分支. 1.Collection.可以保存一个或多个对象,将其保存为一个序列.Collection又可以细 ...
- Web前端基础——jQuery(三)
本文主要从以下几方面介绍jQuery应用中的内容: 1 jQuery 节点遍历2 jQuery 中的过滤器3 jQuery 属性操作4 jQuery Dom节点操作5 几个jQuery例子6 jQue ...
- 基于IDEA的bs三层架构
1.在大学的老师讲课中,可能会用到myeclipse或者eclipse来进行编译运行.其中的缺点就是要自行去下载开发所需要的一些jar包,要考虑都版本的不同造成的影响,且ORACLE和MYSQL的链接 ...
- Navicat安装及简单使用
一.安装 下载完之后,直接解压出来就能用,看一下解压之后的目录: 双击打开下面这个文件(可以把它添加一个桌面快捷方式,或者添加到任务栏): 然后会提示你输入注册码: 回到navicat的解压出来的文件 ...
- TUM数据集rgbd_benchmark工具的使用方法
# 在学习视觉slam过程中,需要对数据集合进行预处理和对slam或者跟踪结果进行评价,TUM提供一组这样的工具,为了自己以后方便查找,于是把它记录下来 一.RGBD_Benchmark工具下载链接: ...