HTTP缓存是如何实现
浏览器是如何知道使用缓存的,其实这都是通过http中,浏览器将最后修改时间发送请求给web服务器,web服务器收到请求后跟服务器上的文档最后修改的时间对比,如果web服务器上最新文档修改时间小于或者等于浏览器发送过来的,则发送304给浏览器,使用缓存版本。
缓存的概念
缓存这个东西真的是无处不在, 有浏览器端的缓存, 有服务器端的缓存,有代理服务器的缓存, 有ASP.NET页面缓存,对象缓存。 数据库也有缓存, 等等。
http中具有缓存功能的是浏览器缓存,以及缓存代理服务器。
http缓存的是指:当Web请求抵达缓存时, 如果本地有“已缓存的”副本,就可以从本地存储设备而不是从原始服务器中提取这个文档。
缓存的好处
缓存的好处是显而易见的, 好处有,
1. 减少了冗余的数据传输,节省了网费。
2. 减少了服务器的负担, 大大提高了网站的性能
3. 加快了客户端加载网页的速度
Fiddler可以方便地查看缓存的header
Fiddler中把header都分门别类的放在一起,这样方便查看。
如何判断缓存新鲜度
Web服务器通过2种方式来判断浏览器缓存是否是最新的。
第一种, 浏览器把缓存文件的最后修改时间通过 header ”If-Modified-Since“来告诉Web服务器。
第二种, 浏览器把缓存文件的ETag, 通过header "If-None-Match", 来告诉Web服务器。
通过最后修改时间, 来判断缓存新鲜度
1. 浏览器客户端想请求一个文档, 首先检查本地缓存,发现存在这个文档的缓存, 获取缓存中文档的最后修改时间,通过: If-Modified-Since, 发送Request给Web服务器。
2. Web服务器收到Request,将服务器的文档修改时间(Last-Modified): 跟request header 中的,If-Modified-Since相比较, 如果时间是一样的, 说明缓存还是最新的, Web服务器将发送304 Not Modified给浏览器客户端, 告诉客户端直接使用缓存里的版本。如下图。
3. 假如该文档已经被更新了。Web服务器将发送该文档的最新版本给浏览器客户端, 如下图。
实例: 打开Fiddler, 然后打开博客园首页。然后F5刷新几次浏览器。 你会看到博客园首页也用了缓存。
与缓存有关的header
我们来看看每个header的具体含义。
Request
Cache-Control: max-age=0 | 以秒为单位 |
If-Modified-Since: Mon, 19 Nov 2012 08:38:01 GMT | 缓存文件的最后修改时间。 |
If-None-Match: "0693f67a67cc1:0" | 缓存文件的Etag值 |
Cache-Control: no-cache | 不使用缓存 |
Pragma: no-cache | 不使用缓存 |
Response
Cache-Control: public | 响应被缓存,并且在多用户间共享, (公有缓存和私有缓存的区别,请看另一节) |
Cache-Control: private | 响应只能作为私有缓存,不能在用户之间共享 |
Cache-Control:no-cache | 提醒浏览器要从服务器提取文档进行验证 |
Cache-Control:no-store | 绝对禁止缓存(用于机密,敏感文件) |
Cache-Control: max-age=60 | 60秒之后缓存过期(相对时间) |
Date: Mon, 19 Nov 2012 08:39:00 GMT | 当前response发送的时间 |
Expires: Mon, 19 Nov 2012 08:40:01 GMT | 缓存过期的时间(绝对时间) |
Last-Modified: Mon, 19 Nov 2012 08:38:01 GMT | 服务器端文件的最后修改时间 |
ETag: "20b1add7ec1cd1:0" | 服务器端文件的Etag值 |
如果同时存在cache-control和Expires怎么办呢?
浏览器总是优先使用cache-control,如果没有cache-control才考虑Expires
ETag
ETag是实体标签(Entity Tag)的缩写, 根据实体内容生成的一段hash字符串(类似于MD5或者SHA1之后的结果),可以标识资源的状态。 当资源发送改变时,ETag也随之发生变化。
ETag是Web服务端产生的,然后发给浏览器客户端。浏览器客户端是不用关心Etag是如何产生的。
为什么使用ETag呢? 主要是为了解决Last-Modified 无法解决的一些问题。
1. 某些服务器不能精确得到文件的最后修改时间, 这样就无法通过最后修改时间来判断文件是否更新了。
2. 某些文件的修改非常频繁,在秒以下的时间内进行修改. Last-Modified只能精确到秒。
3. 一些文件的最后修改时间改变了,但是内容并未改变。 我们不希望客户端认为这个文件修改了。
实例, 打开Fiddler, 打开博客园首页。 你可以看到很多图片,或者CSS文件都是用了缓存。 这些都是通过比较ETag的值,来判断文件是否更新了。
浏览器不使用缓存
CTRL+F5强制刷新浏览器,或者设置IE。 可以让浏览器不使用缓存。
1. 浏览器发送Http request, 给Web 服务器, header中带有Cache-Control: no-cache. 明确告诉Web服务器,客户端不使用缓存。
2. Web服务器将把最新的文档发送给浏览器客户端.
实例:
打开Fiddler, 打开博客园首页, 然后按CTRL+F5强制刷新浏览器,你将看到
Pragma: no-cache的作用和Cache-Control: no-cache一模一样。 都是不使用缓存。
Pragma: no-cache 是HTTP 1.0中定义的, 所以为了兼容HTTP 1.0. 所以会同时使用Pragma: no-cache和Cache-Control: no-cache
直接使用缓存,不去服务器验证
按F5刷新浏览器和在地址栏里输入网址然后回车。 这两个行为是不一样的。
按F5刷新浏览器, 浏览器会去Web服务器验证缓存。
如果是在地址栏输入网址然后回车,浏览器会"直接使用有效的缓存", 而不会发http request 去服务器验证缓存,这种情况叫做缓存命中,如下图
实例: 比较第一次访问博客园主页和第二次博客园主页
1. 启动Fiddler, 用firefox打开博客园主页, 发现有50多个session。
2. 按CTRL+X将Fiddler中的所有session删除。 关闭firefox,重新打开一个firefox,打开博客园主页。 发现只有30多个session.
分析; 少了的session是因为firefox直接用了缓存,而没有发http request。
如何设置IE不使用缓存
打开IE。点击工具栏上的, 工具->Internet选项->常规->浏览历史记录 设置. 选择“从不”。然后保存。
然后点击“删除” 把Internet临时文件都删掉 (IE缓存的文件就是Internet临时文件)。
公有缓存和私有缓存的区别
Cache-Control: public 指可以公有缓存, 可以是数千名用户共享的。
Cache-Control: private 指只支持私有缓存, 私有缓存是单个用户专用的。
HTTP缓存是如何实现的更多相关文章
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- 哪种缓存效果高?开源一个简单的缓存组件j2cache
背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...
- ASP.NET Core 中间件之压缩、缓存
前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是 Microsoft.AspNetCore.Respons ...
- ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core
背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...
- [Java 缓存] Java Cache之 DCache的简单应用.
前言 上次总结了下本地缓存Guava Cache的简单应用, 这次来继续说下项目中使用的DCache的简单使用. 这里分为几部分进行总结, 1)DCache介绍; 2)DCache配置及使用; 3)使 ...
- [原创]mybatis中整合ehcache缓存框架的使用
mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...
- 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- 深究标准IO的缓存
前言 在最近看了APUE的标准IO部分之后感觉对标准IO的缓存太模糊,没有搞明白,APUE中关于缓存的部分一笔带过,没有深究缓存的实现原理,这样一本被吹上天的书为什么不讲透彻呢?今天早上爬起来赶紧找了 ...
- 缓存工厂之Redis缓存
这几天没有按照计划分享技术博文,主要是去医院了,这里一想到在医院经历的种种,我真的有话要说:医院里的医务人员曾经被吹捧为美丽+和蔼+可亲的天使,在经受5天左右相互接触后不得不让感慨:遇见的有些人员在挂 ...
- .net 分布式架构之分布式缓存中间件
开源git地址: http://git.oschina.net/chejiangyi/XXF.BaseService.DistributedCache 分布式缓存中间件 方便实现缓存的分布式,集群, ...
随机推荐
- new static() 和 new self() 的区别异同
长夜漫漫啊! 今天领导本地搭建一个站.发现用PHP 5.2 搭建不起来,站PHP代码里面有很多5.3以上的部分,领导让苦逼我更改在5.2下能运行. 改着改着发现了一个地方 return new sta ...
- outlet删除不完全
今天在用iOS写个计算器的时候,遇到的一个小bug,新手,太新了,不之所错. 直接上码: Terminating app due to uncaught exception 'NSUnknownKey ...
- Python3 错误处理 和 测试
try 让我们用一个例子来看看try的机制: try: print('try...') r = 10 / 0 except ZeroDivisionError as e: print('except: ...
- 重力加速度陀螺仪传感器MPU-6050(一)
MPU-60X0 对陀螺仪和加速度计分别用了三个16 位的ADC,将其测量的模拟量转化 为可输出的数字量.为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的,陀螺仪可测范围为±250,±50 ...
- 【BZOJ】3309: DZY Loves Math 莫比乌斯反演优化
3309: DZY Loves Math Description 对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007) ...
- zoom 用法
from: http://www.jb51.net/css/40285.html 其实Zoom属性是IE浏览器的专有属性,Firefox等浏览器不支持.它可以设置或检索对象的缩放比例.除此之外,它还有 ...
- MVC-Model数据注解(二)-自定义
由于系统的数据注解肯定不适合所有的场合,所以有时候我们需要自定义数据注解. 自定义数据注解有两种,一种是直接写在模型对象中,这样做的好处是验证时只需要关心一种模型对象的验证逻辑,缺点也 ...
- C# - 中断模式下的调试
1. 设置断点 选中需要设置断点的行,右键选择断点插入断点,此行左侧显示红色圆形标志.或者F9 有几个条件断点类型: a. 条件断点 b. 命中次数,大于,几倍于,大于等于你设置的断点次数此时中断 c ...
- iOS新上线注意事项
上传不出现构建版本 现在苹果要求先上传版本,然后在提交审核,但是现在经常上传完应用后,不出现构建版本,等待很久很久,也不出现,那么怎么解决,我告诉你~~尼玛的苹果是自己数据丢包了,结果就造成你不出现构 ...
- Python的库和资源(转)
Python的库和资源: http://blog.sina.com.cn/s/blog_3cb6a78c0100hpaq.html Python 常用模块: http://www.pythonclub ...