1.什么是缓存
一个使用缓存Cache的站点会监听客户端向服务器端发出的请求,并保存服务器端的回应—如HTML页面、图片等文件。接着,如果有另外一个客户端使用相同的URL发送请求,它能够使用之前已经保存下来的反馈文件,而不是再次向服务器发出请求。
缓存的好处:
减少延迟:缓存离客户端更近,从缓存中请求内容比从源服务器所用时间更少,减少了服务器的负担,提高了网站性能;
降低网络负荷:因为缓存文件(副本)可以重复使用,大大降低了用户的带宽使用,加快了客户端加载网页的速度;
2.缓存分类及其区别
Cache-Control: public 指可以公有缓存,可以是数千名用户共享的。
Cache-Control: private 指只支持私有缓存,私有缓存是单个用户专用的。
3.如何判断缓存新鲜度
Web服务器通过2种方式来判断浏览器缓存是否是最新的:
第一种:浏览器把缓存文件的最后修改时间通过 header的"If-Modified-Since "来告诉Web服务器。
第二种:浏览器把缓存文件的ETag通过header的"If-None-Match" 来告诉Web服务器。
4.HTTP缓存相关的header
4.1 expires
expires是HTTP/1.0的东西,是响应消息头字段,在响应HTTP请求时告诉浏览器,在过期时间前可以使用缓存副本;
如:
date表示当前response发送的时间,expires表示副本过期时间,这是一个绝对时间,表示在指定的时间段内缓存,使用expires有可能存在时间不一致的问题,如果服务器端和客户端的时间不一致,可能会导致无法使用缓存,所以建议使用相对时间;
Expires的值是HTTP协议日期,HTTP协议日期是格林威治时间而不是你的本地时间。
4.2 cache-control
http/1.1引入了Cache-Control响应头参数,它与Expires的作用一致,都是指明当前缓存副本的有效期,控制浏览器是直接从浏览器缓存取数据还是重新发请求到服务器取数据,只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires;
cache-control的值可以是如下的值:
public:响应会被缓存,并且在多用户间共享(公用缓存)。正常情况,如果要求HTTP认证,响应会自动设置为private;
private:响应只能够作为私有的缓存(如在一个浏览器中),不能在用户间共享,这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效;
no-cache:响应不会被缓存,而是避过缓存实时向服务器端请求资源;
no-store:在任何条件下响应都不会被缓存,并且不会被写入到客户端的磁盘里;
max-age=[秒]:表示在这个时间范围内缓存是新鲜的无需更新。类似Expires时间,不过这个时间是相对的而不是绝对的。也就是某次请求成功后在多少秒内缓存是新鲜的,这指定了一个时间而不是一个时间段;
s-maxage=[单位:秒 seconds]:类似于 max-age, 但是它只用于公享缓存 (e.g.proxy);
min-fresh:客户端可以接收响应时间小于当前时间加上指定时间的响应;
max-stale:客户端可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户端可以接收超出超时期指定值之内的响应消息;
must-revalidate:响应在特定条件下会被重用以满足接下来的请求,但是必须到服务器端去验证它是不是仍然是最新的;
proxy-revalidate:类似于must-revalidate但不适用于代理缓存;
如:
4.3 Last-Modified/If-Modified-Since
Last-Modified/If-Modified-Since要配合Cache-Control使用,Last-Modified为响应类型,If-Modified-Since为请求类型;
Last-Modified:服务器端资源的最后修改时间;web服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since:缓存资源的最后修改时间;web服务器收到请求后发现有头If-Modified-Since则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源被改动过,则响应整个资源内容(写在响应消息包体内)HTTP200;若最后修改时间较旧,说明资源无新修改,则响应HTTP304(无需包体,节省浏览),告知浏览器继续使用所保存的cache;
如:
4.4 校验值Etag/If-None-Match
Etag/If-None-Match也要配合Cache-Control使用。
Etag:服务器端资源的Etag值;服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(标识资源的状态,生成规则由服务器端决定)。Apache中,ETag的值默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的值。
If-None-Match:缓存资源的Etag值;当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match(Etag的值)。web服务器收到请求后发现有头If-None-Match,则与被请求资源的相应校验串进行比对,决定返回200或304;
为什么有了last-modified还要使用etag?
主要是为了解决Last-Modified无法解决的一些问题。
1.某些服务器不能精确得到文件的最后修改时间,或者与代理服务器时间不一致等情形,这样就无法通过最后修改时间来判断文件是否更新了;
2.Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内被修改多次的话,它将不能准确标注文件的修改时间;
3.一些文件的最后修改时间改变了,但是内容并未改变,我们不希望客户端认为这个文件修改了,因为这会导致文件没法使用缓存;
补充:
Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304;
HTTP1.1引入了一个新的验证器称为Etag,它是每次响应资源改变时,由服务器生成的唯一标识符,由于服务器控制ETag如何生成,当缓存发起If-None-Match请求的时候,如果Etag匹配,就可以确定响应资源其实是一样的;
如图:
if-none-match和etag的值相同,说明文件没有更新,服务器将返回304告诉客户端使用缓存;
补充:
5.用户行为与缓存
浏览器缓存行为还有用户的行为有关:
示例:CTRL+F5强制刷新浏览器,让浏览器不使用缓存;
浏览器通过cache-control:no cache或者pragma:no cache明确告诉服务器比使用缓存,所以服务器总会把新文件发给浏览器且Pragma: no-cache的作用和Cache-Control: no-cache一样都是不使用缓存。
Pragma: no-cache 是HTTP1.0中定义的,所以为了兼容HTTP1.0会同时使用Pragma: no-cache和Cache-Control: no-cache
6.哪些请求无法被缓存?
无法被浏览器缓存的请求:
1.HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求;
2.需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的;
3.经过HTTPS安全加密的请求(参考:
http://www.ruanyifeng.com/blog/2011/02/seven_myths_about_https.html);
4.POST请求无法被缓存;
5.HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存;
7.流程的流程总结
浏览器第一次请求时:
浏览器再次请求时:
参考文章:
http://kb.cnblogs.com/page/166267/
http://www.cnblogs.com/TankXiao/archive/2012/11/28/2793365.html
http://www.cnblogs.com/skynet/archive/2012/11/28/2792503.html
阅读(1656) | 评论(0) | 转发(0) |