Adamwu1992 / adamwu1992.github.io

My Blog
2 stars 0 forks source link

HTTP缓存机制 #2

Open Adamwu1992 opened 6 years ago

Adamwu1992 commented 6 years ago

缓存是一种保存资源副本并且在下次请求时直接使用该副本的技术。当web缓存发现请求的资源已经被缓存,会拦截该请求,并且直接返回对应的副本,并不会去服务器下载资源,这样可以节省资源并且提升效率。

常见的http缓存只能储存GET请求的响应。

缓存控制(Cache-Control)

HTTP1.1定义了Cache-Control用来区分对缓存机制的支持情况。

禁止缓存

缓存中不储存任何客户端的请求和服务端的响应,每次客户端请求都会下载完整的服务端响应。

Cache-Control: no-store

强制确认缓存

每次客户端发起的请求都会到服务器确认是否过期,如果返回304才使用本地缓存。 Pragma: no-cache是兼容HTTP1.0而存在的字段,效果类似,当同时存在是,优先级更高。

Cache-Control: no-cache
Pragma: no-cache

共有缓存和私有缓存

默认是private。如果手动制定为public,响应就会被任何人缓存,包括中间代理、CDN等。private表示该缓存只能用于浏览器中。

Cache-Control: pirvate
Cache-Control: public

设置缓存时间

max-age=[seconds],表示在这个时间段之内缓存是可以直接使用的,不需要去服务器验证。在chrome的调试工具中状态码为200(from cahce)。 与之类似的还有一个字段为Expires,这个字段的值是一个绝对时间,表示在这个时间之前缓存是可用的,但是如果客户端和服务器的时间存在误差,缓存判断可能会不准确。 Expires是为了兼容HTTP1.0的标准而存在的,优先级低于max-age。

Cache-Control: max-age= 31536000
Expires: Thu, 20 Jul 2017 02:18:41 GMT

缓存对比策略

Cache-Control字段定义了一个响应内容能否被缓存以及缓存时间,HTTP还定义了一套机制来判断缓存内容是否应该被更新。

资源最后修改时间

首次请求服务器资源时,响应头部返回该资源的最后修改时间Last-Modified,当客户端再次发起相同的请求是,请求头部会用If-Modified-Since或者If-Unmodified-Since带上最后修改时间一起发送给服务器,服务器如果发现最后修改时间相同就会返回一个没有body的304响应,表示缓存可用,否则,返回新的响应内容并且更新Last-Modified

资源内容是否修改

首次请求时,服务器会根据资源内容计算出一个类似md5的值,用ETag字段返回到客户端。当再次请求该资源时,客户端会把ETag值放在If-Match或者If-None-Match里发送给服务器,如果资源内容没有改变,服务器会返回304,否则,返回新的响应内容并且更新ETag

对比Last-Modified和ETag

ETag计算需要消耗一定的服务器资源,如果是分布式服务器的情况,需要确保ETag的算法一致。Last-Modified不能识别一秒内多次修改的情况,而且在某些情况下,文件被修改但是内容没有变化,也会改变资源的修改时间。

Adamwu1992 commented 6 years ago
zooeyking commented 1 year ago

强制缓存: Expires或者Cache-Control: max-age,
分析下下面这种情况:我请求到了资源 max-age: 10分钟, 然后更改本地时间为一个小时后,这个时候expires 和 max-age 就没什么区别了吧?看了那么多缓存的文章都讲max-age比expires高明,为了解决客户端服务端时间戳不一致问题,想问下这种情况下怎么就高明了?相对时间跟绝对时间在这种情况下不都一样的效果吗?只要有客户端时间参与比较 就没办法规避掉这个问题吧?