HTTP缓存通过设置一些头加以掌握,有一部分是掌握要不要缓存、怎么缓存以及缓存多久的,还有一部分是决定缓存过期往后怎么处理的。
下面只列出最紧张的:

缓存掌握Cache-Controlpublic:公共,可以被客户端和代理做事器(如Nginx、Squid)缓存private:私有,只能被当前客户端缓存no-store:不缓存,客户端不掩护缓存no-cache:并不是不缓存,但是每次都会要求做事器,可以合营ETag和Last-Modified来避免相应重复的内容,适用于须要显示最新内容的场景max-stale:客户端可以设置它来利用已经由期的缓存,单位为秒,这个韶光是已经由期了多少秒的意思must-revalidate:由于客户端可以设置max-stale来利用已经由期的缓存,做事器可以设置它来逼迫客户端不许可利用过期的缓存,必须重新要求做事器Pragma:比较Cache-Control,它是不支持相应头的,常日是为了向后兼容HTTP/1.0缓存韶光max-age:间隔要求发起的韶光的秒数,Cache-Control指令之一Expires:过期韶光(GMT格式),和max-age类似,但是Expires受客户端韶光影响,是HTTP/1.0的标准,max-age是它的改良版,优先级为:max-age -> Expires缓存校验(缓存过期后通过比较来检讨是否连续利用)Last-Modified:做事端在相应头里面设置此项来奉告客户端资源的修正韶光(GMT格式),客户端会不才次要求时自动加上If-Modified-Since: ,做事端以此来比对缓存是否有更新ETag(Entity Tags):依赖Last-Modified来检讨缓存有缺陷,比如文件的修正韶光变了但是内容没有变,又比如它只能精确到秒,而ETag是比对内容,可以理解为md5值,做事端相应ETag后客户端会不才次要求时自动带上If-None-Match: 。
ETag比Last-Modified开销大,如果可以用Last-Modified只管即便用Last-Modified

把稳private的运用处景,比如个人中央的url是/userinfo.php,所有人的url都是相同的,这个时候如果用了public走了代理缓存,会导致所有人共享一个缓存,以是这种时候须要利用private。

实例

php获取网站速度PHP开辟若何应用HTTP缓存来加速你的网站速度 SQL

缓存一分钟,一分钟内直接读取本地缓存,一分钟后重新要求做事器:

Cache-Control: public, max-age=60, must-revalidate

上面这种办法一旦缓存过期就会重新要求做事器返回最新的内容,如果内容并没有变革,那不是白传了?有没有办法在缓存过期往后判断一下如果内容没有改变则连续用本地的缓存呢?很大略!
ETag可以帮到你,有效期内直接读取本地缓存,过期后跟做事器比对ETag,相同则做事器会返回304表示缓存还可以连续用,而不返回实际内容,节约了韶光和带宽。

缓存一分钟,一分钟内直接读取本地缓存,一分钟往后跟做事器比对ETag,如果ETag没有变革,那么接下来的一分钟内还是直接读取本地缓存:

Cache-Control: public, max-age=60, must-revalidateETag: abc

每次都要跟做事器比对ETag是否相同,适宜更新轻微比较频繁并且须要及时显示最新内容的资源:

Cache-Control: public, no-cacheETag: abc

不缓存:

Cache-Control: no-store

一图胜千言

结合以上知识点,以做事真个视觉,结合需求来看详细须要怎么设置,画个流程图:

动态脚本的缓存

我们一样平常会在Nginx上配置静态文件的缓存,而常常忽略了动态页面和API的缓存,实在它们也是可以设置缓存的,在代码里面实现更加灵巧,以PHP为例,新建一个文件命名为cache.php:

header('Cache-Control: public, max-age=60, must-revalidate');$time = date('H:i:s');$data = 666;$etag = md5($data);if($_SERVER['HTTP_IF_NONE_MATCH'] == $etag){ header(\公众HTTP/1.1 304 Not Modified\公众); header('ETag: '.$etag); exit;}else{ header('ETag: '.$etag, true, 200);}echo $time.'|'.$data;

上面的代码设置缓存一分钟,过期之后客户端须要和做事端通过比对ETag来确认缓存是否可以连续利用。
现在可以一贯点击刷新按钮看看效果,奇怪,怎么不是直接读本地缓存,总是要求到做事器返回304了呢?

浏览器的刷新策略

点击浏览器的刷新按钮或者F5,要求头会加上Cache-Control: max-age=0,Ctrl + F5强刷会在要求头加上Cache-Control: no-cache,以是这两个操作都会导致浏览器放弃读取本地缓存而直接要求做事器。
点击链接跳转和退却撤退或者提高按钮是不会加上这些头的。

如果想看200 from disk cache读取本地缓存的效果,我们须要一个页面来做个跳转:

<!DOCTYPE html><html lang=\公众zh\公众><head> <meta charset=\"大众utf-8\"大众></head><body> <p><a href=\公众./cache.php\"大众>这个页面被缓存了,打开看看吧。
</a></p></body></html>

ajax缓存

如果是ajax要求怎么实现缓存呢?也是一样的,JS只要掌握好ETag和Last-Modified就好,jquery的ajax方法里有个ifModified可以做到自动处理。

$.ajax({ type: 'GET', url: 'api.php', cache: true, ifModified: true, success: function(data, status, xhr){ if(data) { console.log(data); } } });});</script></body></html>

如果希望每次都读取最新的内容,如果内容没更新就读缓存,可以这样做:

header('Cache-Control: no-cache');$data = 'abcdef';$etag = md5($data);if($_SERVER['HTTP_IF_NONE_MATCH'] == $etag) { header(\"大众HTTP/1.1 304 Not Modified\"大众); header('ETag: '.$etag); exit;}header('ETag: '.$etag);echo $data;