HTTP 缓存
缓存:存储指定资源的一份拷贝,并在下次请求该资源时提供该拷贝。
缓存需要合理配置,因为并不是所有资源都是永久不变的:重要的是对一个资源的缓存应截止到其下一次发生改变(即不能缓存过期的资源)。
缓存的种类有很多,其大致可归为两类:私有与共享缓存。
私有服务器缓存
只能用于单独用户。
比如浏览器设置中的“缓存”选项:浏览器缓存拥有用户通过 HTTP 下载的所有文档。
这些缓存为浏览过的文档提供向后/向前导航,保存网页,查看源码、缓存内容的离线浏览等功能,可以避免再次向服务器发起多余的请求。
共享代理缓存
共享缓存可以被多个用户使用。例如,ISP 或你所在的公司可能会架设一个 web 代理来作为本地网络基础的一部分提供给用户。这样热门的资源就会被重复使用,减少网络拥堵与延迟。
缓存控制
1. Cache-control
头
Cache-Control: private 响应的内容只能被唯一的用户缓存,不可以被共享缓存存储。隐私模式下的浏览器会通过这种方式存储缓存。
Cache-Control: public 针对需要进行http身份验证的页面或者一些不能被顺利缓存的响应码,通过定义public以支持缓存
Cache-Control: no-cache
不缓存内容
Cache-Control: no-store
Cache-Control: no-cache, no-store, must-revalidate 缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。must-revalidate: 在使用一些老的资源前强制验证状态判断其是否过期。
Cache-Control: max-age=31536000 max-age是距离请求发起的时间的秒数。判断缓存是否过期。针对图片、css、js等静态资源。
为什么定期或者频繁更新的资源要设置一个相对长一些的过期时间?
不频繁更新的文件会使用特定的命名方式:在URL后面(通常是文件名后面)会加上版本号。这么做也存在一个弊端,所有引用这个资源的地方都需要更新链接。
web开发者们通常会采用自动化构建工具在实际工作中完成这些琐碎的工作。当低频更新的资源(js/css)变动了,只用在高频变动的资源文件(html)里做入口的改动。
缓存验证
1. ETag : 资源的特定版本的标识符
缓存的强校验器。如果资源请求的响应头里含有ETag, 客户端可以在后续的所有请求的头中带上 If-None-Match
头来验证缓存。
如果内容没有改变,Web服务器不需要发送完整的响应。如果内容发生了变化,使用ETag有助于防止资源的同时更新相互覆盖(“空中碰撞”)。
2. Last-Modified
一次性的弱校验器。如果响应头里含有这个信息,客户端可以在后续的一次请求中带上 If-Modified-Since
来验证缓存。
3. Vary
HTTP 响应头决定了对于后续的请求头
,如何判断是请求一个新的资源还是使用缓存的文件。
只有当前的请求和原始(缓存)的请求头跟缓存的响应头里的Vary都匹配,才能使用缓存的响应。
Vary: User-Agent 通过UA判断是否使用缓存的页面。移动版和桌面的客户端的请求头中的User-Agent不同,避免在不同的终端展示错误的布局。
Vary: User-Agent, Accept-Encoding 服务器应以 User-Agent 和 Accept-Encoding 两个请求首部字段来区分缓存版本。