想要使用浏览器缓存,需要浏览器和web服务器进行沟通(缓存协商),确认是否使用浏览器缓存,有些童鞋可能会有 疑问了,浏览器缓存明明在本地,为什么非要请求web服务器?能不能不请求web服务器直接使用浏览器缓存呢?答案是肯定的,能,我们只需要在响应的头信息中添加过期时间即可,在过期时间之前,浏览器将不会再次请求web服务器,而是直接使用本地缓存。
如何添加浏览器缓存截止期?
不同的web服务器添加过期时间的方法也不相同,我们以Apache服务器为例,为文件添加过期时间。
LoadModule expires_module modules/mod_expires.so
<IfModule expires_module>
ExpiresActive on
ExpiresDefault "now plus 1 day"
</IfModule>
首先去掉Apache中mod_expires.so前面的#,如果没有该模块,可以自行添加。其次就是对该模块进行配置,ExpiresActive on代表启用过期时间,ExpiresDefault "now plus 1 day" 代表默认的过期时间为1天,除了ExpiresActive,ExpiresDefault,还有ExpiresByType,关于Apache的expires模块更多配置信息可以
点击这里。
我们的设置是否成功了呢?,我们来验证下吧。
我们看到在比未开启过期模块之前多了两项,”Cache-Control“和“Expires”,这就是我们需要的过期时间了,有些童鞋该有疑问了,为什么要使用两个,两者到底有什么区别呢?
”Expires“和”Cache-Control“
跟缓存协商类似,过期时间同样有两种表达方式,”Expires“和”Cache-Control“。Expires给出是一个确切的时间点,是绝对时间,Cache-Control给出的是过期秒数,是相对时间,一般情况下,它们代表着相同的过期时间,但是也有特殊情况,例如用户本地的时间和服务器的时间不一致,这样两者起到的作用就不一样了,下面我们来看个例子。
服务器时间为10月2日11:55:30,用户的时间为10月2日13:55:30,缓存的时间为1小时,由于用户的本地时间比服务器晚了两小时,如果按照Expires指定的过期时间来判断的话,上述情况的过期时间为10月2日 12:55:30,而用户请求的时候时间已经是13:55:30,换句话说用户向该服务器请求的所有资源都会立即过期。但是Cache-Control不一样,它指定了缓存的相对时间,并且这个是针对浏览器本地而言,也就是说,当用户与10月2日13:55:30请求的时候,过期时间为10月2日 14:55:30秒。
一般我们使用的操作系统都会使用基于GMT的标准时间,本地时间通过时区来进行偏移计算,而HTTP中使用的也是GMT时间,所以一般不会因为时区导致本地和服务器相差数个小时。但是没人能够保证用户的本地时间和服务器的一致,因此除了Expires外使用Cache-Control是明智之举,当HTTP头信息中同时包含了Expires和Cache-Control的时候,浏览器会优先考虑Cache-Control,如果没有Cache-Control,浏览器则会服从Expires的指示。
验证过期时间是否生效
既然添加了过期时间,那么就需要来验证下过期时间是否真的起到效果了。我们仍然需要借助HttpFox。
304?那不是缓存协商的结果吗,难道使用Expires也会返回304,还是Expires没有生效呢?其实都不对,在解释这个问题之前我们先来了解下我们经常使用的请求方法,了解过后这个问题就一目了然了。
如何请求页面?
对于使用浏览器请求页面,相信大家都不会陌生,但是你知道浏览器请求页面一共有几种方法吗,每种请求方法的具体含义吗,下面就跟跟随小编一起来看看浏览器是如何请求页面的吧。
Ctrl+F5:强制刷新,相信不少朋友听过并且用过这种方法,它使得网页以及所有组件都直接向web服务器发送请求,并且不使用缓存协商,这样的目的是获取所有内容的最新版本。
F5:一般刷新,相比于Ctrl+F5,相信这种方法我们更加常用,它同等于单击浏览器的刷新按钮。它允许浏览器在请求的中附加必要的缓存协商,但不允许浏览器直接使用本地缓存,也就是说,它能够让Last-Modified发挥效果,但是对Expires无效。
在浏览器地址栏输入URL后按回车:相信这是大家使用最多的方法,等同于这种刷新方法的还有两种操作,一种是浏览器地址栏的”转到“按钮(现在很多浏览器已经找不到这种按钮了),另一种是通过超链接跳转到此页。这几种方式允许浏览器以最少的请求来获取网页的数据,浏览器会对所有没有过期的内容直接使用本地缓存,所以Expires标记只对这种请求方式有效。
看过上述三种请求方式,对于刚才Expires没有生效的问题是不是已经有答案了,因为我们习惯于使用F5做第二次请求,而F5又不允许浏览器直接使用本地缓存,所以就出现了304的情况,知道了原理,想要看到Expires的效果,是不是已经有方法了,不错,使用第三种请求方式即可。
动态网页是否需要手动添加过期时间?
我们使用缓存协商的时候已经知道了web服务器不会为动态网页添加Last-Modified和ETag,那么过期时间呢,是否也需要手动添加呢?幸运的是,过期时间不用我们来手动添加了,web服务器同时也会为动态网页添加过期时间。
缓存协商和过期时间使用心得
1.web服务器会自动为静态文件添加缓存协商(Last-Modified和ETag),但不会为动态文件添加,如果开启过期模块,则动态文件和静态文件都能够获得过期时间(Expires和Cache-Control)。
2.web服务器会自动为静态文件添加缓存协商,过期时间的添加则需要借助web服务器的Expires模块,即使web服务器没有为静态文件添加过期时间,浏览器也会自动给静态文件添加一个过期时间,这个过期时间就是浏览器关闭的那一刻,浏览器关闭之前访问过的静态网页都在过期时间内。因此,对于静态文件,请求的结果完全遵照上述三种请求方式返回的结果。
3.动态文件如果存在缓存协商(Last-Modified或ETag),不存在过期时间(Expires和Cache-Control),Ctrl+F5返回200,第二种和第三种请求方式返回304,因为不知道过期时间,所以无法直接调用本地缓存。如果存在过期时间(Expires或Cache-Control),不存在缓存协商(Last-Modified和ETag),第一种第二种请求方式都会返回200,第三种请求方式会直接使用本地缓存。如果不存在缓存协商(Last-Modified和ETag相关判断)和过期时间(Expires和Cache-Control),三种请求方式返回的结果都是200。特别说明:IE浏览器(IE8)使用第三种方式请求网页,不论上述哪种情况,都会返回本地缓存,这是IE浏览器跟其他浏览器的区别,google浏览器也比较特殊,存在过期时间的时候在浏览器地址栏输入URL后按回车本来应该返回本地缓存,但是google浏览器却返回304(静态文件html也是如此,但是如果html中包含了图片,css,js这类的静态文件,它们仍然使用本地缓存),只有当进行超链接跳转的时候才会使用本地缓存。