如今的Web应用愈来愈复杂,体验愈来愈好。相应的,资源文件也愈来愈大,若是能让客户端在资源没更新的状况下,直接取用缓存的数据,那么不只资源加载的更快,服务器压力更小,也为绿色地球作出了一份贡献。程序员
程序员向来是追求最优,在设法缓存静态资源之后,你们又找到了一些方法来缓存动态生成的内容。看来程序员们都是环境保护主义者(笑。缓存
从HTTP/1.0-HTTP/1.1,一共产生了3种控制缓存的方法:服务器
Cache-Control(响应头,HTTP/1.1)代理
- Last-Modified(响应头),If-Modified-Since(请求头) - Etag(响应头),If-None-Match(请求头)
以上就是HTTP控制缓存的方法。code
除了这些,在第二个还有If-Unmodified-Since,第三个还有If-Match。但这两个响应头不是为了控制缓存,而是为了确认修改的资源的一致性。以后会介绍。资源
Expires: <http-date>
其中 <http-date> 的格式以下:io
Date: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT Example: Fri, 03 Nov 2017 03:22:39 GMT
当设置了Expires后,客户端在此日期以前都不会去请求服务器,而是直接从缓存中取。
不过这样也有一个问题:若是彻底不去请求服务器的话,在资源过时以前若是资源有更新,客户端仍是使用着以前的资源。因此就产生了下面更加高级的缓存控制方法(第3、第四项方法)。ast
不过还有一个方法能解决这个问题:将资源的Expires设置为一个足够长的时间,而资源名为资源的Hash值,这样资源更新了之后,也使用的是不一样的名称。那么就不存在上面的问题了。date
Expires只能设置具体的日期,这样的话,若是客户端与服务器的时间不一致,会致使缓存时间不正确,还有可能直接致使缓存失效。语法
HTTP/1.1的Cache-Control配合If-Modified-Since或If-None-Match则完美的解决了这个问题。
Cache-Control比较经常使用的指令以下:
可缓存性
过时控制
再验证
其余
上面列表中向服务器确认缓存是否有效的技术手段就是下文介绍的 Last-Modified/If-Modified-Since
和 ETag/If-None-Match
。
Last-Modified: <http-date>
Last-Modified头是服务器告诉客户端此资源的最后修改时间,客户端则会将资源和这个时间都储存起来。以后,根据Cache-Control的指令,若是须要同服务器确认资源的有效性的时候则会将这个时间放在If-Modified-Since头中,供服务器进行比较,是返回304仍是200。
If-Modified-Since头只会在GET和HEAD请求被附加进请求头。
If-Unmodified-Since: <http-date>
通常来讲在PUT, POST等方法使用,表示该次请求更新的资源的日期为<http-date>,若是服务器检测到现存资源的日期不为<http-date>(即已经被其余的方式更新了),则会失败并返回412。
ETag: W/"<etag_value>" ETag: "<etag_value>"
If-None-Match: "<etag_value>"[, "<etag_value>"...] If-None-Match: W/"<weak_etag_value>"[, "<weak_etag_value>"]
若是将上面的 Last-Modified / If-Modified-Since
应用在动态的数据上的话,基本上没有可行性。那么就有了此方式的缓存。
在第一次请求的时候,服务器会附带ETag头。ETag的值是根据响应的内容来进行生成的,通常来讲是内容(+其余一些标识的)哈希值。以后,根据Cache-Control的指令,若是须要同服务器确认资源的有效性的时候则会将这个etag_value放在If-None-Match头中,供服务器进行比较,是返回304仍是200。
在ETag的值前若是有W/
则表示这是一个弱Etag。弱ETag相等意味着这两个内容语义上是相等的,强ETag相等则表示内容每个字节都相等。
举个弱ETag的例子:返回的数据中带有log信息,而两次返回的数据是相同的,log不一样。
还有一种语法:
If-None-Match: *
,基本上用在PUT, POST等上,用于上传。表示要求上传的文件在服务器上不存在。
If-Match: "<etag_value>"[, "<etag_value>"...] If-Match: W/"<weak_etag_value>"[, "<weak_etag_value>"]
对于GET, HEAD等请求,若是资源的ETag匹配上If-Match的值,则返回资源,不然返回412。
对于PUT, POST等请求,若是现有资源的Etag匹配上If-Match的值,那么进行写操做,不然失败返回412。
----- 记得点赞 -----