http中有关缓存相关的几个字段
转载自:http://blog.csdn.net/lifeibo/article/details/5979572
Expires、Cache-Control、Last-Modified、 ETag是RFC 2616(HTTP/1.1)协议中和网页缓存相关的几个字段。前两个用来控制缓存的失效日期,后两个用来验证网页的有效性。要注意的是, HTTP/1.0有一个功能比较弱的缓存控制机制:Pragma,使用HTTP/1.0的缓存将忽略Expires和Cache-Control头。我们这里以Apache2.0服务器为例,只讨论HTTP/1.1协议。
Expires
Expires字段声明了一个网页或URL地址不再被浏览器缓存的时间,一旦超过了这个时间,浏览器都应该联系原始服务器。RFC告诉我们:“由于推断的失效时间也许会降低语义透明度,应该被谨慎使用,同时我们鼓励原始服务器尽可能提供确切的失效时间。”
对于一般的纯静态页面,如html、gif、jpg、css、js,默认安装的Apache服务器,不会在响应头添加这个字段。Firefox浏览器接受到相应后,如果发现没有Expires字段,浏览器根据文件的类型和“Last-Modified”字段来推断出一个合适的失效时间,并存储在客户端。推测出的时间一般是接受到响应时间后的三天左右。
Apache的expires_module模块可以在Http响应头部自动加上Expires字段。在Apache的httpd.conf文件中进行如下配置:
#启用expires_module模块
LoadModule expires_module modules/mod_expires.so
# 启用有效期控制
ExpiresActive On
# GIF有效期为1个月
ExpiresByType image/gif A2592000
# HTML文档的有效期是最后修改时刻后的一星期
ExpiresByType text/html M604800
#以下的含义类似
ExpiresByType text/css “now plus 2 month”
ExpiresByType text/js “now plus 2 day”
ExpiresByType image/jpeg “access plus 2 month”
ExpiresByType image/bmp “access plus 2 month”
ExpiresByType image/x-icon “access plus 2 month”
ExpiresByType image/png “access plus 2 month”
对于动态页面,如果在页面内部没有通过函数强制加上Expires,例如header(”Expires: ” . gmdate(”D, d M Y H:i:s”) . ” GMT”),Apache服务器会把Wed, 11 Jan 1984 05:00:00 GMT作为Expires字段内容,返回给浏览器。即认为动态页面总是失效的。而浏览器仍然会保存已经失效的动态页面。
可以发现Firefox浏览器总是缓存所有页面,不管失效、不失效还是没有声明失效时间。即使缓存中声明了一个网页的实效日期是1970-01 - 01 08:00:00,浏览器仍然会发送该文件在缓存中的Last-Modified和ETag字段。如果在服务器端验证通过,返回304状态,浏览器就还会使用此缓存。
Cache-Control
Cache-Control字段中可以声明多些元素,例如no-cache, must-revalidate, max-age=0等。这些元素用来指明页面被缓存最大时限,如何被缓存的,如何被转换到另一个不同的媒介,以及如何被存放在持久媒介中的。但是任何一个 Cache-Control指令都不能保证隐私性或者数据的安全性。“private”和“no-store”指令可以为隐私性和安全性方面提供一些帮助,但是他们并不能用于替代身
份验证和加密。
Apache的mod_cern_meta模块允许文件级Http响应头部的控制,同时它也可以配置Cache-Control头(或任何其他头)。响应头文件是放在原始目录的子目录中,根据原始文件名所命名的一个文件。具体用法请参阅Apache的官方网站。其中Cache-Control : max-age表示失效日期。如果没有启动mod_cern_meta模块,Apache服务器会把Expires字段中的日期换算成以秒为单位的一个
delta值,赋值给max-age。如果启动mod_cern_meta模块,并且配置了max-age值,Apache会将这个覆盖Expires字段。同时,max-age隐含了Canche-Control: public。这样浏览器接受到的Cache-Control : max-age和Expires值就是一致的。
如果失效日期Cache-Control : max-ag=0或者是负值,浏览器会在对应的缓存中把Expires设置为1970-01-01 08:00:00。
Last-Modified
Last-Modified和ETag是条件请求(Conditional Request)相关的两个字段。如果一个缓存收到了针对一个页面的请求,它发送一个验证请求询问服务器页面是否已经更改,在HTTP头里面带上” ETag”和”If Modify Since”头。服务器根据这些信息判断是否有更新信息,如果没有,就返回HTTP 304(NotModify);如果有更新,返回HTTP 200和更新的页面内容,并且携带新的”ETag”和”LastModified”。
使用这个机制,能够避免重复发送文件给浏览器,不过仍然会产生一个HTTP请求。
一般纯静态页面本身都会有Last-Modified信息,Apache服务器会读取页面文件中的Last-Modified信息,并添加到http响应头部。
对于动态页面,如果在页面内部没有通过函数强制加上Last-Modified,例如header(”Last-Modified: ” . gmdate(”D, d M Y H:i:s”) . ” GMT”),Apache服务器会把当前时间作为Last-Modified,返回给浏览器。
无论是纯静态页面还是动态页面,Firefox浏览器巧妙地按照接受到服务器响应的时间设置缓存页面的Last-Modified,而不是按照http响应头部中的Last-Modified字段。
ETag
既然有了Last-Modified,为什么还要用ETag字段呢?因为如果在一秒钟之内对一个文件进行两次更改,Last-Modified就会不正确。因此,HTTP/1.1利用Entity Tag头提供了更加严格的验证。
Apache服务器默认情况下,会对所有的静态、动态文件的响应头添加ETag字段。在Apache的httpd.conf文件中可以通过FileETag指令配置该选项。
FileETag指令配置了当文档是基于一个文件时用以创建 Etag(entity tag)响应头的文件的属性。在Apache 1.3.22及以前,ETag的值是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。如果一个目录的配置包含了‘FileETag INode MTime Size’而其一个子目录包含了‘FileETag -INode’那么这个子目录的设置(并会被其下任何没有进行覆盖的子目录继承)将等价于‘FileETag
MTime Size’。
在多台负载平衡的服务器环境下,同一个文件会有不同的etag或者文件修改日期,浏览器每次都会重新下载。设置‘FileETag None’可以使响应头不再包含ETag字段。
APACHE服务的内容过期设置
Apache配置摘录及解释
i. 过期相关设置
LoadModule headers_module modules/mod_headers.so
#Load 修改header的模块。
LoadModule expires_module modules/mod_expires.so
#Load 设定过期header的模块。
Header append Via: CCN-BJ-4-502
#增加一个Via header,值配置成设备的hostname。
KeepAliveTimeout 60
#设置连接的保持时间为60秒。
ExpiresActive On
#启用过期header功能。
ExpiresDefault A604800
#缺省过期时间为“访问后的604800秒”
<Directory /data/download>
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
ExpiresByType text/html A300
#text/html类型文件的过期设置为“访问后的300秒”
ExpiresByType text/css A259200
#text/css类型文件的过期设置为“访问后的259200秒”
ExpiresByType application/x-javascript A300
# application/x-javascript类型文件的过期设置为“访问后的300秒”
ExpiresByType image/gif A2592000
#image/gif类型文件的过期设置为“访问后的2592000秒”
ExpiresByType application/x-shockwave-flash A2592000
# application/x-shockwave-flash类型文件的过期设置为“访问后的2592000秒”
</Directory>
上述配置文件中load的两个模块:mod_headers.so 和mod_expires.so 可以让Apache具有对header的一些定制功能。
ExpiresByType: 表示按照文件类型-MIME-TYPE设定过期策略;
A300: 表示在Access后300秒后过期;
ExpiresByType text/css A2592000: 表示Mime type是text/css的文件,在Access后2592000秒过期。
ExpiresDefault A604800: 表示除了单独制定的文件类型等过期策略外的其他内容,按照这个缺省的策略设定:访问后604800秒过期。
上面的方法可以实现根据web发布的不同文件类型,针对不同的发布目录进行过期策略设置。在按照如上方法设置后,Apache会自动的产生两个相关的http header,举例如下:
HTTP/1.1 200 OK
Date: Tue, 27 Mar 2007 17:44:21 GMT
Server: Apache/2.0.54 (Unix)
Last-Modified: Thu, 25 Jan 2007 07:45:45 GMT
ETag: “72df3a-93-99499c40”
Accept-Ranges: bytes
Content-Length: 147
Cache-Control: max-age=2592000
Expires: Thu, 26 Apr 2007 17:44:21 GMT
Via: CCN-BJ-4-575
Keep-Alive: timeout=60, max=100
Connection: Keep-Alive
Content-Type: image/gif
Length: 147 [image/gif]
其中:Date + Max-age = Expires. Max-age是个时间长度,对应web server上面设置的过期时间;Expires是根据max-age算出来的过期时间点,两者是一致的,不同cache在判断内容是否过期时会严格比较系统时间和上述过期时间,或者比较age(在cache中存住的时间长度)和max-age的值。
http中有关缓存相关的几个字段的更多相关文章
- HTTP请求中的缓存(cache)机制
http://www.chaorenmao.com/blog/?p=79 流程 当资源第一次被访问的时候,HTTP头部如下 (Request-Line) GET /a.html HTTP/1.1Ho ...
- 谈谈MVC项目中的缓存功能设计的相关问题
本文收集一些关于项目中为什么需要使用缓存功能,以及怎么使用等,在实际开发中对缓存的设计的考虑 为什么需要讨论缓存呢? 缓存是一个中大型系统所必须考虑的问题.为了避免每次请求都去访问后台的资源(例如数据 ...
- HTTP中缓存相关
1.客户端如何区分缓存命中和未命中 两种情况下,返回的状态码都是200,客户端有一个方法可以判断,就是使用Date首部,将Date首部与当前时间进行比较,如果响应中时间日期值比较早,客户端可以认为这是 ...
- 浏览器缓存相关的Http头介绍:Expires,Cache-Control,Last-Modified,ETag
转自:http://www.path8.net/tn/archives/2745 缓存对于web开发有重要作用,尤其是大负荷web系统开发中. 缓存分很多种:服务器缓存,第三方缓存,浏览器缓存等.其中 ...
- iOS中dyld缓存的实现原理是怎样的?
在iOS开发中,为了提升系统的安全性,很多系统库文件都被打包到一个缓存的文件当中即dyld缓存,那大家对dyld缓存了解多少呢?今天小编将和大家分享的就是一位iOS大神对dyld缓存的使用分析,一起来 ...
- ios 缓存相关信息收集
链接:http://www.cnblogs.com/pengyingh/category/353093.html 使用NSURLCache让本地数据来代替远程UIWebView请求 摘要: 原文作者: ...
- hibernate中的缓存机制
一.为什么要用Hibernate缓存? Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源中的数 ...
- 浏览器缓存相关http头
近期看雅虎黄金34条,学习下优化站点性能的方法. 当中有一条:"为文件头指定Expires或Cache-Control",详细来说指对于静态内容:设置文件头过期时间Expires的 ...
- ASP.NET Core中的缓存[1]:如何在一个ASP.NET Core应用中使用缓存
.NET Core针对缓存提供了很好的支持 ,我们不仅可以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中.对于分布式缓存,.NET Core提供了针对 ...
随机推荐
- LeetCode 445——两数相加 II
1. 题目 2. 解答 2.1 方法一 在 LeetCode 206--反转链表 和 LeetCode 2--两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可. /** * Def ...
- solidity事件详解
很多同学对Solidity 中的Event有疑问,这篇文章就来详细的看看Solidity 中Event到底有什么用? 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊. ...
- 3.配置HDFS HA
安装zookeeper下载zookeeper编辑zookeeper配置文件创建myid文件启动zookeeper配置HDFS HA配置手动HA配置自动HA启动HDFS HA namenode负责管理整 ...
- Swift-创建UIButton(其他UI组件雷同)
let button = UIButton.init(frame: CGRectMake(, , , )) button.setTitle("按钮", forState: UICo ...
- <Effective C++>读书摘要--Inheritance and Object-Oriented Design<一>
1.Furthermore, I explain what the different features in C++ really mean — what you are really expres ...
- 软工网络15团队作业4——Alpha阶段敏捷冲刺-3
一.当天站立式会议照片: 二.项目进展 昨天已完成的工作: 依靠HTML 逻辑框架等技术完成程序界面前端的实现. 明天计划完成的工作: 依靠css 逻辑框架等技术完成程序界面前端的实现. 工作中遇到的 ...
- MySQL中使用trim()删除两侧字符
在某些情况下由于程序没处理好,导致数据表中有些字段的值会有空白字符出现,如 这样如果在严格比对name时会匹配不到.trim()函数可以解决这样的问题 作为trim()函数的子集,ltrim()函数是 ...
- tcp传送报文
707 void tcp_init_xmit_timers(struct sock *sk)708 {709 inet_csk_init_xmit_timers(sk, &tcp_wr ...
- 【python】python sqlalchemy core
SQLAlchemy是和很多数据库进行交互的一个库,他可以让你创建model,让你可以以一种Python中面向对象的方式进行查询.使得你的代码和数据库可以分开,也就是减轻他们之间的依赖.让你进行数据库 ...
- bzoj4555-求和
题目 \(S(i,j)\)表示第二类斯特林数,求: \[ f(n)=\sum _{i=0}^n\sum _{j=0}^iS(i,j)*2^j*j! \] 分析 公式推理很简单,关键是用到了第二类斯特林 ...