进行web开发时,为了提高网站的访问速度,我们通常会把页面静态资源(JavaScript,css,img,font...)进行缓存,这就需要用到浏览器端的缓存策略,其实缓存原理并不复杂,今天我们一探究竟。
在介绍HTTP缓存原理之前我们先了解一下web端常见的缓存方式:
1,服务端缓存(CDN代理服务)
2,数据库缓存
3,浏览器缓存(HTTP缓存,localStorage,sessionStorage,cookie,indexDB...)
今天我们要说的HTTP缓存即是浏览器缓存的一种。
浏览器加载页面资源的流程是下面这样的...
访问页面时,浏览器会根据资源的HTTP请求头来判断是从客户端缓存加载资源,还是从服务器加载资源,如果客户端加载资源走的是强缓存,则资源直接从客户端加载,如果走的是协商缓存则资源从服务端加载,服务端再根据请求头来判断该资源是否有效,如果资源有效,服务器将返回304状态码,告诉浏览器继续使用浏览器端缓存的资源,如果资源已经失效,服务器会重新返回完整的资源给浏览器。
通过分析以上资源加载流程,有同学不禁会问,浏览器加载资源时是如何区分走的是强缓存还是协商缓存的,以及服务端如何区分资源是否失效的呢?
在浏览器第一次加载页面资源时,服务端会在响应头中返回该资源为强缓存或者协商缓存。
强缓存响应头标识:cache-control,expires 协商缓存响应头标识:etag,last-modified
其中cache-control会根据不同的值,决定资源是否是走强缓存。
下面分析一下两者的区别:
一,强缓存:
1,Expires
该请求头是HTTP1.0时定义的规范。指的是资源过期时间,浏览器会通过对比服务器端设置的时间和客户端时间来判断资源是否过期。改规范唯一的缺点就是客户端时间和服务端时间不一致时会导致缓存失效。因此会和Cache-Control一块使用。
2,Cache-Control
该请求头是HTTP1.1时定义的规范。有如下几个常用值:
max-age:缓存有效期
public:客户端和代理服务器都可以缓存资源
private:只允许客户端缓存资源
immutable:永不过期
no-cache:资源不进行强缓存,走协商缓存
no-store:客户端和服务端都不缓存
常用组合:
cache-control: max-age=xxxx,public
客户端和服务器都可以缓存资源,在max-age时间内访问资源从浏览器缓存获取,如果用户做了刷新操作就向服务器重新请求资源。
cache-control: max-age=xxxx,private
客户端可以缓存资源,代理服务器不可用,在max-age时间内访问资源从浏览器缓存获取。
cache-control: max-age=xxxx,immutable
在max-age时间内访问资源从浏览器缓存获取,即使用户做了刷新操作也不会重新想服务器发起请求。
cache-control: max-age=no-cache
跳过强缓存走协商缓存
cache-control: no-store
客户端、服务器都不会缓存资源,也就没有所谓的强缓存、协商缓存了。
Cache-Control优先级大于Expires
二,协商缓存:
1,Last-Modified/if-Modified-Since
浏览器第一次请求某个资源时,服务器会返回响应头Last-Modified即资源的最后一次修改时间,如果走协商缓存,下次浏览器再次请求时会带上if-Modified-Since,其值就是响应头中的Last-Modified。
2,ETag/if-None-Match
ETag原理和Last-Modified类似,ETag代表资源的唯一标识。只要资源的大小内容等发生变化ETag就会重新生成。
ETag优先级大于Last-Modified