http学习之路
摘要
在请求的页面里有些静态文件(图片,css,js)不是常常变化的,将这些文件存储起来,也是客户端优化用户浏览体验的一个好方法。http缓存做为web性能优化的重要手段,可是对于前端来讲只是知道浏览器会对静态文件进行缓存,但为何被缓存,缓存是怎么失效的并不清楚。下面为你们介绍http的缓存机制。
http缓存分类
缓存分为强制缓存和协商缓存,强制缓存在缓存数据未失效状况下,不须要和服务器进行交互。而协商缓存须要进行和服务器进行比较和判断是否进行缓存。
两种缓存同时存在的状况下,强制缓存优先于协商缓存。
强制缓存
1. Expires
expires的值是告诉浏览器的缓存过时时间(值为GMT时间,即格林尼治时间),即下次请求时,没有到达过时时间,浏览器会直接使用缓存数据。
虽然这种方式添加了缓存控制,节省了流量,但仍是存在不少问题
(1)
因为客户端时间是服务器没办法控制的时间,假如用户改变了客户端时间,就可能形成一些缓存的更新不及时
(2)
缓存过时后,无论文件有咩有发生变化,浏览器都会从新请求服务器
2. Catch-Control
针对以上浏览器和服务器时间不一致问题,加入了新的缓存方案,服务器不直接告诉浏览器过时时间,而是告诉浏览器一个相对时间Cache-Control=10秒,意思是10秒内,直接使用浏览器缓存。css
协商缓存
强制缓存的弊端很明显,都是经过时间判断是否请求服务器加载,可是若是文件没有发生变化,就会形成浪费服务器的资源。
协商缓存有两组报文结合使用
Last-modified
为了节省服务器资源,再次改变方案。浏览器和服务器协商,服务器每次返回文件时,都会告诉浏览器文件在服务器上最近修改的时间,请求的过程以下:前端
- 浏览器请求静态资源Demo.png
- 服务器读取磁盘,返回给浏览器文件,并带上文件上次修改时间Last-Modified(GMT标准格式)
- 当浏览器缓存文件过时时,浏览器会带上If-Modified-since(等于上次请求的last-modified)请求服务器。
- 服务器比较请求头里的If-modified-since和文件上次修改的时间,若是文件一致就继续使用浏览器的缓存(304),不一致就从新请求服务器并返回last-modified
- 循环请求。。。。
虽然这个方式比上面三个方式都有进一步的优化,浏览器检测文件是否有变化,若是没有变化,就直接使用缓存文件仍是有些问题:
- last-modified是使用(GMT)时间,只能精确到秒,若是文件在一秒以内改变不少次,浏览器就没办法去识别并请求新的文件。
- 若是文件通过屡次修改,可是内容没有变化,服务器须要从新返回请求文件。
Etag
为了解决文件修改时间不精确的问题,浏览器再和服务器进行协商,此次不返回时间,返回文件惟一标识Etag,只有当文件内容改变时,Etag才会改变。请求过程以下:web
- 浏览器请求静态资源demo.png
- 服务器读取磁盘,把demo.png文件返回给浏览器,并带上文件的惟一标识Etag
- 当浏览器的缓存文件过时时,浏览器带上If-None-Match(等于上次上次的Etag)再次请求服务器
- 服务器比较请求头的If-None_Match和文件的Etag,若是一致就继续使用缓存文件(304),不一致带上Etag从新请求服务器。
- 循环请求。。。
关于Pragma
当该字段值为no-cache的时候,会告诉浏览器不要对该资源缓存,即每次都得向服务器发一次请求才行。
res.setHeader('Pragma', 'no-cache') //禁止缓存
res.setHeader('Cache-Control', 'public,max-age=120') //2分钟复制代码
经过Pragma来禁止缓存,经过Cache-Control设置两分钟缓存,可是从新访问咱们会发现浏览器会再次发起一次请求,说明了Pragma的优先级高于Cache-Control
关于Cache-Control
咱们看到Cache-Control中有一个属性是public,那么这表明了什么意思呢?其实Cache-Control不光有max-age,它常见的取值private、public、no-cache、max-age,no-store,默认值为private,各个取值的含义以下:
- private: 客户端能够缓存
- public: 客户端和代理服务器均可缓存
- max-age=xxx: 缓存的内容将在 xxx 秒后失效
- no-cache: 须要使用对比缓存来验证缓存数据
- no-store: 全部内容都不会缓存,强制缓存,对比缓存都不会触发
因此咱们在刷新页面的时候,若是只按F5只是单纯的发送请求,按Ctrl+F5会发现请求头上多了两个字段Pragma: no-cache和Cache-Control: no-cache。
缓存的优先级
上面咱们说过强制缓存的优先级高于协商缓存,Pragma的优先级高于Cache-Control,那么其余缓存的优先级顺序怎么样呢?网上查阅了资料得出如下顺序(PS:有兴趣的童鞋能够验证一下正确性告诉我):
Pragma > Cache-Control > Expires > ETag > Last-Modified