一、http缓存 (http缓存只能缓存get请求响应的资源)
第一次请求时:
服务器服务器返回200,浏览器通过response header的Cache-Control/Expires字段来设置是否需要进行缓存该资源。
客户端向服务端发起请求时,如果浏览器有缓存且没有失效的话,会从浏览器获取数据而不是从服务端获取。
第二次请求时
比较当前时间和上一次返回200时的时间差,如果没有超过cache-control设置的max-age,则没有过期,命中强缓存,不发请求直接从本地缓存读取该文件(如果浏览器不支持HTTP1.1,则用expires判断是否过期);
如果时间过期,则向服务器发送header带有If-None-Match和If-Modified-Since的请求。
服务器收到请求后,优先根据Request Headers 的字段If-None-Match(Etag值)判断被请求的文件有没有做修改,Etag值一致则没有修改,命中协商缓存,返回304;如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200;;
如果服务器收到的请求没有Etag值,则将If-Modified-Since和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回304;不一致则返回新的last-modified和文件并返回200;;
(图片引用来自下面的参考文献:《强缓存和协商缓存区别》)
1. 强制缓存:
- Expires:
http1.0的规范,值为时间格式的字符串。这是http1.0时的规范;它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源
- Cache-Control: http1.1
Cache-Control设置值
name 解析 max-age 缓存在XX秒后失效 private 客户端可以缓存,只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存 public 客户端和代理服务器可以缓存。(前端的同学,可以认为public和private是一样的) no-Cache 需要对比缓存(协商缓存)来验证缓存数据,不使用本地缓存。 no-store 直接禁止浏览器缓存数据
2.对比缓存(协商缓存):(304返回缓存,200返回header和body)
- lastModified (响应头-资源最后修改的时间):
第一次请求,服务器返回的header中会有Last-Modify,这是一个时间,标识资源最后一次修改的时间(精确到秒)。
- If-Modify-Since(请求头)
当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存
- Etag(响应头-资源唯一标识):
在HTTP/1.1出现,web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识,返回的是一个hash值(生成规则由服务器决定)
- If-None-Match(请求头):
当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match则与被请求资源的相应校验串进行比对,决定是否命中协商缓存;
==ETag和Last-Modified的区别优缺点:==
1.Etag要优于Last-Modified。Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度;但是一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET。
2.在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值;
3.在优先级上,服务器校验优先考虑Etag。
参考文献: 强缓存和协商缓存区别