http缓存
1. https缓存应用
能够帮助服务器提高并发性能,很多资源不需要重复请求,直接从浏览器中获取
2. 浏览器加载页面简单流程:
- 浏览器根据http请求头判断是否命中强缓存,如果命中则直接加载缓存中的资源,并不会将请求发送到服务器(强缓存 200(from cache))
- 如果未命中强缓存,浏览器会将资源加载请求发送到服务器,服务器判断浏览器本地缓存是否失效,若未失效则浏览器不会返回资源信息,浏览器继续从缓存中加载资源。(协商缓存 304)
- 若未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存。(新请求 200)
3. https缓存分类
强缓存
强缓存利用http返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。Cache-Control优先级高。
Expires
缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点,是一个绝对时间。是服务器响应头字段,告诉浏览器在过期时间之前浏览器都可以直接在缓存中取数据,无需再次请求。例Expires:Thu,31 Dec 2022 23:59:59 GMT。【缺点:当客户端时间被修改后,服务端和客户端时间偏差大,会导致缓存混乱,因此有了Cache-Control】
Cache-Control
是一个相对时间,指定一个时间长度值。例Cache-Control:max-age=3600。
包括字段有:
- max-age=t:缓存内容在t秒后失效【主要属性】
- private:客户端可以缓存
- public 客户端和代理服务器都可以缓存
- no-cache:需要使用协商缓存(服务器)来验证缓存数据
- no-store:所有数据都不会缓存
协商缓存
若未中强缓存,协商缓存需要对比是否可以进行缓存。浏览器第一次请求数据时,服务器会将缓存标识与数据一起响应给客户端,当浏览器再次请求时,客户端先将缓存标志发送给服务器,服务器根据此标识进行判断,若未失效返回状态码304,浏览器可以使用缓存数据。
根据缓存标识 Last-Modified/If-Modified-Since 或者 ETag/If-None-Match 来判断是否命中缓存。ETag/If-None-Match优先级高
Last-Modified/If-Modified-Since
- Last-Modified,第一次请求资源时,响应头中会返回该字段,告诉浏览器资源的最后修改时间。
- If-Modified-Since,浏览器再次请求时,请求头中会包含该字段,该值为之前的Last-Modified,服务器收到后进行判断是否命中协商缓存,命中返回304 NotModified,未命中返回整体数据以及状态码200。
ETag/If-None-Match
- ETag(entity tag)是服务器响应头中返回的一个校验码,可以保证每一个资源是唯一的,资源变化会导致ETag变化。
- If-None-Match 存放在请求头中,值为返回的ETag校验码,服务器根据该值对比校验码判断是否命中缓存,不同则响应整个资源内容以及返回状态码200,相同则只响应header以及状态码304。
为什么有Last-Modified还需要ETag?
首先Etag HTTP1.1推出的。服务器响应时,通过次字段告诉浏览器当前资源在服务器生成的唯一标识。为了解决几个Last-Modified难解决的问题:
1 Last-Modified标注的时间只能精确到秒级,若在秒内更细致的时间里文件被修改则不能准确的标注修改时间。
2 若某些文件定期生成,但内容没有任何变化,但Last-Modified改变了,导致文件没办法使用缓存。