考虑缓存的内容:
-css
-js文件
-logo、图标
-html文件
-可以下载的内容
不应该被缓存的内容:
-业务敏感的GET请求
html页面
html页面缓存的设置主要是在<head>标签中嵌入<meta>标签,这种方式只对页面有效,对页面上的资源无效
html页面禁用缓存的设置如下:
<meta http-equiv="pragma" content="no-cache">
//仅有IE浏览器才识别的标签,不一定会在请求字段加上Pragma,但的确会让当前页面每次都发新请求
<meta http-equiv="cache-control" content="no-cache">
//其他主流浏览器识别的标签
<meta http-equiv="expires" content="0">
//仅有IE浏览器才识别的标签,该方式仅仅作为知会IE缓存时间的标记,你并不能在请求或响应报文中找到Expires字段
html设置缓存如下:
<meta http-equiv="Cache-Control" content="max-age=7200" />
//其他主流浏览器识别的标签
<meta http-equiv="Expires" content="Mon, 20 Aug 2018 23:00:00 GMT" />
//仅有IE浏览器才识别的标签
私有缓存(浏览器级缓存)
私有缓存只能用于单独的用户:Cache-Control: Private
共享缓存(代理级缓存)
共享缓存可以被多个用户使用: Cache-Control: Public
为什么要有Etag,Last-Modefied有什么问题?
1.一些资源的最后修改时间改变了,但是内容没改变,使用Last-modified看不出内容没有改变。
2.Last-modified 只能精确到秒。某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新。
3.Etag的精度比Last-modified高,属于强验证,要求资源字节级别的一致,优先级高。如果服务器端有提供ETag的话,必须先对ETag进行Conditional Request
JS、CSS等静态资源更新了,怎么让有缓存的浏览器重新加载新资源:
一般来说文件内容改变了,会更新版本号、hash值,相当于请求另一个文件。
可以在请求后携带随机的参数,每次就会访问新的资源
可能经常需要变动的文件: Cache-Control: no-cache / max-age=0
设置max-age: 0跟浏览器缓不缓存有关系吗?s-max-age的作用?
https://hzu-zuoxiong.gitbooks.io/frontend_note/browser/liu-lan-qi-huan-cun.html
在chrome浏览器中返回的200状态会有两种情况:
1、from memory cache
从内存中获取/一般缓存更新频率较高的js、图片、字体等资源
2、from disk cache
从磁盘中获取/一般缓存更新频率较低的js、css等资源
这两种情况是chrome自身的一种缓存策略,这也是为什么chrome浏览器响应的快的原因。其他浏览返回的是已缓存状态,没有标识是从哪获取的缓存。
如果设置长缓存资源更新了咋办,如何及时更新,弊端是什么
设计etag算法 4、ETAG哪些hash算法
资源过期了咋办,如何判断资源是否过期
reference:https://www.cnblogs.com/chenqf/p/6386163.html
缓存规则解析
为方便理解,认为浏览器存在一个缓存数据库,用于存储缓存信息。
在客户端第一次请求数据时,此时缓存数据库中没有对应的缓存数据,需要请求服务器,服务器返回后,将数据存储至缓存数据库中。
根据命中缓存是否需要重新向服务器发起请求来分类,将其分为两大类:强制缓存,对比缓存
强缓存如果命中缓存不需要和服务器端发生交互,而协商缓存不管是否命中都要和服务器端发生交互。
强制缓存优先级高于对比缓存,当执行强制缓存的规则时,如果缓存生效,直接使用缓存,不再执行对比缓存规则。
已存在缓存数据时,仅基于强制缓存,请求数据的流程如下
强制缓存在缓存数据未失效的情况下,可以直接使用缓存数据,那么浏览器是如何判断缓存数据是否失效呢?在没有缓存数据的时候,浏览器向服务器请求数据时,服务器会将数据和缓存规则一并返回,缓存规则信息包含在响应header中。
对于强制缓存来说,响应header中会有两个字段来标明失效规则:Expires,Cache-Control
使用chrome的开发者工具,可以看到对于强制缓存生效时,网络请求的情况
Expires
Expires的值为服务端缓存返回的到期时间,即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据。
由于使用具体时间,如果时间表示出错或者没有转换到正确的时区都可能造成缓存生命周期出错;到期时间是由服务端生成的,但是客户端时间可能跟服务端时间有误差,这就会导致缓存命中的误差。
Expires是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,两个同时存在时Cache-Control 的优先级更高。
Cache-Control
Cache-Control是最重要的规则,常见的取值有private(默认)、public、max-age,no-cache、no-store。
private: 客户端可以缓存
public: 客户端和代理服务器都可缓存
max-age=xxx: 缓存的内容将在xxx秒后失效
no-cache: 需要使用对比缓存来验证缓存数据。强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证的请求到服务器。不是字面意思上的不缓存。
no-store: 所有内容都不会缓存,强制缓存、对比缓存都不会触发
图中Cache-Control仅指定max-age,所以默认为private,缓存时间为31536000秒(365天)就是说,在365天内再次请求这条数据,都会直接获取缓存数据库中的数据,直接使用。
已存在缓存数据时,仅基于对比缓存,请求数据的流程如下
基于对比缓存的流程下,不管是否使用缓存,都需要向服务器发送请求
缓存的资源到期了并不意味着资源内容发生了改变,如果和服务器上的资源没有差异,实际上没有必要再次请求。客户端和服务器端通过某种验证机制验证当前请求资源是否可以使用缓存。
浏览器第一次请求数据之后会将数据和响应头部的缓存标识存储起来。再次请求时会带上存储的头部字段,服务器端验证是否可用。如果返回304 Not Modified,代表资源没有发生改变可以使用缓存的数据,获取新的过期时间。反之返回200就相当于重新请求了一遍资源并替换旧资源。
对比缓存,需要进行比较判断是否可以使用缓存。
浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给客户端,客户端将二者备份至缓存数据库中。
再次请求数据时,客户端将备份的缓存标识发送给服务器,服务器根据缓存标识进行判断,判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。
304 Not Modified资源未修改,可使用缓存
This is used for caching purposes. It tells the client that the response has not been modified, so the client can continue touse the same cached versionof the response.
通过两图的对比,可以发现,对比缓存生效状态码为304,并且报文大小和请求时间大大减少。原因是服务端在进行标识比较后,只返回header部分,通过状态码通知客户端使用缓存,不再需要将报文主体部分返回给客户端。
对于对比缓存来说,缓存标识的传递是着重需要理解的,它在请求header和响应header间进行传递。
一共分为两种标识传递:
Last-Modified / If-Modified-Since
Etag / If-None-Match(优先级高于Last-Modified / If-Modified-Since)
Last-Modified:服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since:
再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的资源最后修改时间。
服务器收到请求后发现有头If-Modified-Since则与被请求资源的最后修改时间进行比对。
若资源的最后修改时间大于If-Modified-Since,说明资源被改动过,则响应整片资源内容,返回状态码200;
若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则响应304,告知浏览器继续使用所保存的cache。
Etag / If-None-Match(优先级高于Last-Modified / If-Modified-Since)
Etag:服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)
If-None-Match:
再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。
服务器收到请求后发现有头If-None-Match则与被请求资源的唯一标识进行比对。
不同,说明资源被改动过,则响应整片资源内容,返回状态码200;
相同,说明资源无新修改,则响应304,告知浏览器继续使用所保存的cache。
总结
强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求直接用缓存;不在时间内,执行比较缓存策略。
比较缓存,将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验;返回304状态码时,浏览器直接使用缓存。