什么的HTTP缓存
简单点说:http缓存是浏览器向服务器请求资源时,会先询问浏览器,如果浏览器有该请求资源副本就可以直接从浏览器缓存中获取而无需再次请求服务器获取资源,因为http缓存对用户访问速度有很大影响。
HTTP缓存优点
- 减少冗余请求,降低服务器压力;
- 减少获取资源时间,提升用户体验;
- 减少重复请求,节省带宽;
HTTP缓存位置
- Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker的话,传输协议必须为 HTTPS。
- Memory Cache 也就是内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。 一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。
- Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。绝大部分的缓存都来自Disk Cache,在HTTP 的协议头中设置。
- Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂,在Chrome浏览器中只有5分钟左右,同时它也并非严格执行HTTP头中的缓存指令
HTTP请求头
HTTP 首部字段根据实际用途被分为以下 4 种类型。
通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。
请求首部字段(Request Header Fields)
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加 内容、客户端信息、响应内容相关优先级等信息。
响应首部字段(Response Header Fields)
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加 内容,也会要求客户端附加额外的内容信息。
实体首部字段(Entity Header Fields)
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更 新时间等与实体有关的信息。
HTTP缓存策略
浏览器再次请求资源时候会在http请求头中带一些字段,告诉服务器使用哪个缓存策略。
强缓存
与强缓存相关的有2个字段:
expires:过期时间。它是一个GMT时间格式的字符串,如果请求时间在此时间之前,则采用缓存数据,如果之后,则会再次请求服务器获取数据。
cache-control:该字段下有几个字段来判断缓存是否有效。
- max-age:有效时间相对值,浏览器会将上一次请求时间和该有效期计算出过期时间,再将该过期时间与当前请求时间进行比较,如果请求时间在过期时间之前,则缓存有效,否则无效。
- no-cache:不使用本地缓存。需要使用协商缓存,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
- no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
- public:可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器,适用于公共缓存服务器的情况。
- private:只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存。
注意:如果cache-control与expires同时存在的话,cache-control的优先级高于expires
协商缓存
当浏览器发现请求资源过期时,并不表示该资源的缓存不能用了,因为该资源在服务器上很可能没有修改,如果直接请求新数据也是资源浪费,所以这个时候需要跟服务器协商这个资源到底还能不能用缓存。此时浏览器会判断缓存中是否有ETag或Last-Modified字段,如果没有,则发起一个http请求,服务器根据请求返回资源;如果有这两个字段,则在请求头中添加If-None-Match字段(有ETag字段的话添加)、If-Modified-Since字段(有Last-Modified字段的话添加)。
注意:如果同时发送If-None-Match 、If-Modified-Since字段,服务器只要比较If-None-Match和ETag的内容是否一致即可;如果内容一致,服务器认为缓存仍然可用,则返回状态码304,浏览器直接读取本地缓存,这就完成了协商缓存的过程
如上图,ETag字段和If-None-Match字段相同,所以请求状态返回304
ETag
和If-None-Match
服务器生成的每个资源的唯一标识符串。
- 浏览器请求资源,服务器会在响应报文头中加入ETag字段。资源更新时,服务器端的ETag值也随之更新;
- 浏览器再次请求资源时,会在请求报文头中添加If-None-Match字段,它的值就是上次响应报文中的ETag的值;
- 服务器会比对ETag与If-None-Match的值是否一致,如果不一致,服务器则接受请求,返回更新后的资源;如果一致,表明资源未更新,则返回状态码为304的响应,可继续使用本地缓存,要注意的是,此时响应头会加上ETag字段,即使它没有变化。
Last-Modified
和If-Modified-Since
二者的值都是GMT格式的时间字符串。
- 浏览器第一次向服务器请求资源后,服务器会在响应头中加上Last-Modified字段,表明该资源最后一次的修改时间;
- 浏览器再次请求该资源时,会在请求报文头中添加If-Modified-Since字段,它的值就是上次服务器响应报文中的Last-Modified的值;
- 服务器会比对Last-Modified与If-Modified-Since的值是否一致,如果不一致,服务器则接受请求,返回更新后的资源;如果一致,表明资源未更新,则返回状态码为304的响应,可继续使用本地缓存,与ETag不同的是:此时响应头中不会再添加Last-Modified字段。
注意:Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
HTML头部常见的缓存配置
<meta http-equiv="Expires" content="0">
<meta http-equiv="Cache-control" content="max-age=0,no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache" content="no-cache">
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。