Http缓存
当你二次加载一个网页的时候,往往比第一次加载要快很多,尤其是一些图片资源的展示更为明显,这背后的原因是什么?其实就是HTTP缓存。缓存是提高HTTP通信效率一种方式:它将上次的请求按一种合理的方式存下来,下次再次加载的时候,如果发现上次缓存依旧有效就可以直接用上次的缓存数据,从而避免或者减少网络请求及数据传输,提高通信效率。看一个狭义的缓存示意[假设只有端上缓存]
原则
HTTP 缓存只能存储 GET 响应,对于其他类型的响应则无能为力
强制缓存与对比缓存
Etag的优先级高于Last-Modified
Expires:
这个字段是HTTP/1.0中的,Expires是需要在服务端配置(具体配置也根据服务器而定),Expires添加的是该资源过期的日期,浏览器会根据该过期日期与客户端时间对比,如果过期时间还没到,则会去缓存中读取该资源,如果已经到期了,则浏览器判断为该资源已经不新鲜要重新从服务端获取。通过这种方式,可以实现直接从浏览器缓存中读取,而不需要去服务端判断是否已经缓存,避免了这次http请求。值得注意的是Expires时间可能存在客户端时间跟服务端时间不一致的问题。所以,建议Expires结合Cache-Control一起使用,大型网站中一起使用的情况比较多见。
Cache-Control:
该字段是HTTP/1.1协议中的,可以是请求头中的或者响应头中的字段。它允许服务器控制客户端缓存收到的响应的方式和时长。 Cache-Control是一个复杂的野兽,具有许多内置功能。 99%的情况下,只需要“cacheability”(可缓存性)和“max-age”。但是Cache-Control可能被某些缓存和浏览器忽略。可以通过将Expires HTTP版本1.0标头字段值设置为早于响应时间的时间来进行模拟。Cache-Control相对于Expires更加具体,细致。若同时设置了Cache-Control和Expires,Cache-Control的优先级高于Expires。
下面就来看看,Cache-Control响应头中常用字段的具体含义:
(1)max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒;
(2)s-maxage:和max-age是一样的,不过它只针对代理服务器缓存而言;
(3)public:指示响应可被任何缓存区缓存;
(4)private:只能针对个人用户,而不能被代理服务器缓存,不能被共享缓存处理;
(5)no-cache:请注意,no-cache不会指示浏览器或代理是否要缓存内容。它只是告诉浏览器和代理在使用它之前验证服务器的缓存内容(这是通过If-Modified-Since,If-Unmodified-Since,If-Match,If-None-Match属性完成的)。因此,发送无缓存值指示浏览器或代理仅仅基于缓存内容的“新鲜度标准”不使用缓存内容。防止旧内容在未经验证的情况下向用户显示的另一种常见方法是Cache-Control:max-age = 0。这会指示用户代理内容是陈旧的,并且应在使用前进行验证。所以no-cache和max-age=0是相同效果。Cache-Control:no-cache 也适用于客户端发出的请求。它是浏览器告诉服务器和任何中间缓存它想要新资源的一种手段。这个和HTTP / 1.0规范中定义的Pragma:no-cache头字段具有相同的目的。但是,它仅为请求标头定义。它没有指定它在响应头中的含义。大多数HTTP/1.0缓存不会识别或服从Cache-Control : no-cache指令。
(6)no-store:指示浏览器应用程序尽最大努力不将其写入磁盘(即不缓存它)。 不应缓存资源的请求并不保证它不会写入磁盘。特别是,HTTP / 1.1定义区分了历史存储和缓存。如果用户导航回上一页,浏览器仍可能会显示已存储在历史记录存储中的磁盘上的页面。根据规范,这是正确的行为。许多用户代理在从历史存储或缓存加载页面时显示不同的行为,具体取决于协议是HTTP还是HTTPS。用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
If-Modified-Since如果提供的日期以来尚未更改,服务器不会发送文档的实际内容。 如果文档的ETag仍然与If-None-Match标头的值匹配,则服务器将不发送实际文档。 If-None-Match和If-Modified-Since都可以出现在同一个请求中,但ETag优先于If-Modified-Since(就是Last-Modified的时间戳的值),因为它被认为更准确(Etag显然比Last-Modified值准确)。