http的缓存过程
1.客户端向服务器请求资源
2.服务器返回资源,并通过响应头决定缓存策略,
3.客户端根据响应头的策略决定是否缓存资源,(假设是),并将响应头与资源缓存下来
4.在客户端再次请求且命中资源的时候,此时客户端去检查上次缓存的缓存策略,
根据策略的不同,是否过期等判断是直接读取本地缓存还是与服务器协商缓存。
强缓存和协商缓存
强缓存
强缓存和两个响应头有关:Expires与Cache-Control
- Expires:是http1.0提出的一个表示资源过期时间的header,它描述的是一个绝对时间,由服务器返回,缺点是受限于本地时间,修改本地时间,可能会造成缓存失败。
res.setHeader("Expires",new Date(Date.now()+1000*20).toGMTString())
res.setHeader("Cache-Control","max-age=20") 告知浏览器该响应本地缓存有效的最长气象
- Cache-Control:出现于HTTP/1.1,优先级高于expires,表示的是相对时间
Cache-Control:public,可以被所有用户缓存,
Cache-Control:private只能被终端浏览器缓存,不允许中继缓存服务器进行缓存
Cache-Control:no-cache先缓存本地,但是不允许直接使用,但是在命中缓存之后必须与服务器验证缓存的新鲜度才能使用。
Cache-Control:no-store不会产生任何缓存
在缓存有效期内命中缓存,浏览器会直接读取本地的缓存资源。当缓存过期之后会与服务器进行协商
协商缓存
当第一次请求时服务器返回的响应头中没有:Expires与Cache-Control或者Expires与Cache-Control过期,又或者它的属性设置为no-cache时,那么浏览器第二次请求时就会与服务器进行协商。
如果缓存和服务器资源的版本一致,就无须再次下载,服务器直接返回304 Not Modified状态码。
如果缓存是旧版本,服务器就会把最新资源的完整内容返回给浏览器,状态码是200 ok。
服务器靠Last-Modified/If-Modified-Since判断缓存是否新鲜
Last-Modified:Mon, 28 Sep 2015 08:06:43 GMT
客户端请求资源时,服务器会把资源的最新修改时间Last-Modified通过响应首部发送给客户端,当再次发送请求时,客户端将服务器返回的修改时间放在请求头If-Modified-Since发送给服务器,服务器对比资源,如果服务器的资源更新,那返回最新的资源,状态码为200,如果首部时间一样,返回304状态码,表示客户端直接用缓存就行。
Etag
ETag:HTTP1.1推出,文件的指纹标识符,如果文件内容修改,指纹会改变。(如果文件进行了修改,Etag就会改变,这里它脱离了时间的约束,它会更加准确。对于 ETag 来说,它就是文件的一个标识,第一次请求服务器会响应一个 ETag,告诉文件文件资源的标识是多少;下次浏览器再去请求服务端的时候,会带着它去,这时候会换一个名称,会带着该值去服务端看,看内容是否发生改变,如果它改变,ETag 的值就会发生改变;如果没有改变,就会告诉我们浏览器使用本地缓存,返回一个 304 的状态码)
If-None-Match:本地缓存失效,会携带此值去请求服务端,服务端判断该资源是否改变,如果没有改变,直接使用本地缓存,返回 304。
ETag:“78437822c-6739”
If-None-Match:“78437822c-6739"
经常改变的文件,适合协商缓存。js,css文件的加载可以加入文件的签名来拒绝缓存
如果不信使用缓存,可以加入签名,如下:
index.css?签名 或 index.签名.js
HTTP压缩过程
- 浏览器发送http request 给web服务器,request中有Accept-Encoding:gzip,delete(告诉服务器,浏览器支持gzip压缩)
- web服务器接到request后,生成原始的response。
- web服务器通过Gzip,来对response进行编码,编码后header中有Content-Type和Content-Length.(压缩后的大小)。并且增加了Content-Encoding:gzip,然后把response发送给浏览器。
- 浏览器接到response后,根据Content-Encoding:gzip对response进行解码,获取原始response