记录一下浏览器缓存&前端缓存&http缓存方式详解
一、HTTP缓存简介
浏览器缓存是指在本地缓存,HTTP 缓存主要是通过请求和响应报文头中的对应 Header 信息,来控制缓存的策略。
HTTP缓存可以缩短网页请求资源的距离,减少延迟,节省网络流量,并且由于缓存文件可以重复利用,降低网络负荷,提高客户端响应。
完整流程图如下:
二、强缓存和协商缓存
根据是否需要重新向服务器发起请求,可分为强缓存和协商缓存
2.1 强缓存
定义:当命中强缓存的时候,客户端不会再请求服务器,直接从缓存中读取内容,并返回HTTP状态码200。
强制缓存,在响应头由 Expires、Cache-Control 和 Pragma控制,
优先级Expires < Cache-Control < Pragma
Expires:值为服务器返回的过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存。(HTTP1.0的属性,缺点是客户端和服务器时间不一致会导致命中误差)
Cache-Control:HTTP1.1属性,优先级更高,以下为常用属性
no-store: 禁用缓存
no-cache:不使用强缓存,每次需向服务器验证缓存是否失效
private/public:private指的单个用户,public可以被任何中间人、CDN等缓存
max-age=:max-age是距离请求发起的时间的秒数
must-revalidate:在缓存过期前可以使用,过期后必须向服务器验证
Pragma
no-cache:效果和cache-control等no-cache一致。
强缓存的资源存储位置
Chrome会根据本地内存的使用率来决定缓存存放在哪,如果内存使用率很高,放在磁盘里面,内存的使用率很高会暂时放在内存里面(from memory cache和from disk cache区别)
2.2 协商缓存
定义:向服务器发送请求,服务器会根据这个请求的请求头的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的响应头通知浏览器从缓存中读取资源
协商缓存,响应头中有两个字段标记规则
Last-Modified / If-Modified-Since
Last-Modified是浏览器第一个请求资源,服务器响应头字段,是资源文件最后一次更改时间(精确到秒)。
下一次发送请求时,请求头里的If-Modified-Since就是之前的Last-Modified
服务器更加最后修改时间判断命中,如果命中,http为304且不返回资源、不返回last-modify
Etag / If-None-Match:Etag 的校验优先级高于 Last-Modified
Etag是加载资源时,服务器返回的响应头字段,是对资源的唯一标记,值是hash码。
浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到请求头里的If-None-Match里
服务器接受到If-None-Match的值后,会拿来跟该资源文件的Etag值做比较,如果相同,则表示资源文件没有发生改变,命中协商缓存。
在精确度上,Etag要优于Last-Modified,Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度 在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。 在优先级上,服务器校验优先考虑Etag。
四、常见操作
4.1 设置不缓存的方法
1.html文件设置meta;
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate">
<meta http-equiv="expires" content="Wed, 26 Feb 1997 00:00:00 GMT">
2.服务端响应添加Cache-Control:no-cache,must-revalidate指令;
3.修改请求头If-modified-since:0或If-none-match;
4.请求url后增加时间戳;
5.服务端设置Cache-Control:private指令,防止代理服务器缓存资源
4.2 Cache-Control: max-age=0 和 no-cache有什么不同?
效果一样,但行为不同。max-age=0是告诉客户端资源的缓存到期应该向服务器验证缓存的有效性。而no-cache则告诉客户端使用缓存前必须向服务器验证缓存的有效性。