http缓存详细分析

天天系统复习一个知识点

http缓存

http缓存主要分为了两类 强缓存(本地缓存)和协商缓存浏览器

浏览器在请求某一资源时,会先获取改资源缓存的header信息,判断是否命中强缓存(expires的信息和cache-control)若命中直接从缓存中获取该资源信息,包括缓存header信息,本次请求根本就不会与服务器进行通讯。此为强缓存(本地缓存)缓存

若是没有命中强缓存,浏览器会发送请求到服务器,请求会携带第一次请求返回的的有关缓存的header字段信息(last-modified/if-modified-since 和 Etag/if-none-Match),由服务器根据请求中相关header信息来比对结果是否协商缓存命中,若命中,则服务器返回新的响应header信息更新缓存中的对应header信息,可是并不返回资源内容,它会告知浏览器能够直接从缓存获取,不然返回最新的资源内容。服务器

获取资源形式     状态码                 发送请求到服务器

强缓存 从缓存取 200(from cache) 否,直接从缓存取
协商缓存 从缓存取 304(not modified) 是,正如其名,经过服务器来告知缓存是否可用spa

强缓存相关的header字段

1 expires,这是http1.0的规范,它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT。若是发送请求的时间在expires以前,那么本地缓存始终有效,不然就会发送请求到服务器来获取资源。代理

2 cache-control:max-age=number,这是Http1.1时出现的header信息。主要是利用该字段的max-age值来进行判断。它是一个相对值,资源第一次的请求时间和cache-control设定的有效期,计算出一个资源过时时间。再拿这个过时时间跟当前的请求时间比较,若是请求时间在过时时间以前,就能命中缓存,不然就不行,cache-control除了该字段外,还有下面几个比较经常使用的设置值。
no-cache : 不使用本地缓存,须要使用协商缓存。
no-store : 直接禁止浏览器缓存数据。(强缓存和协商缓存都不行),每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。(经常使用于银行等重要业务)
public : 能够被全部的用户缓存,包括终端用户和cdn等中间代理服务器
private : 只能被终端用户缓存,不容许CDN等中继缓存服务器对其缓存unix

注意:若是cache-control与expires同时存在的话,cache-control的优先级高于expires。code


协商缓存

协商缓存都是由服务器来肯定缓存资源是否可用的,因此客户端与服务器端经过某种标识进行通讯,从而让服务器判断请求资源是否能够缓存访问,
这里涉及到下面两组header字段。这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(last-modified或者ETag),则后续请求则会带上对应的请求字段(if-modified-since或者if-none-match),若响应头没有last-modified或者Etag字段,则请求头也不会有对应的字段。cdn

1,第一次和服务器交互,服务器返回资源 在response的header加上last-modified的header.这个header表示这个资源在服务器上的最后修改时间blog

2,第二次请求这个资源,浏览器会在request header加上if-modified-since的header.这个header的值就是上一次请求时返回的last-modified的值。服务器再次收到资源请求。根据浏览器传过来的if-modified-since和资源在服务器上的最后修改时间判断资源是否有变化,若是没有发生变化则返回
304 not modified .可是不会返回资源内容。若是有变化,就正常返回资源内容和更新last-modified字段。当服务器返回304 not modified的响应时,response header中不会再添加last-modified的字段。由于既然资源没有变化,那么last-modified也就不会改变.ip

Etag/if-none-Match
这两个值是由服务器生产的每个资源的惟一标识字符串,只要资源有变化就这个值就会改变,其判断过程和last-modified/if-modified-since相似,与last-modified不同的是。当服务器返回304 not
modified的响应 response header中还会把这个etag返回,即便这个eTag跟以前没有变化。

**Etag比较的是文件资源的特征值,而Last-Modifield则比较的是文件资源的最后的修改时间。这两个实际上是相辅相成的,不是有了Etag就不应有Last-Modifield,有了Last-Modifield就不应有Etag,同时传入服务器时,服务器会根据本身的缓存机制进行选择要使用哪一个,甚至能够两个都进行参考

好比img确定判断last-modified更方便。其余文件可能比较etag更方便
**

既生last-modifed何生ETag

你可能会以为使用last-modified已经足以让浏览器知道本地的缓存副本是否足够新,为何还要Etag呢。http1.1 etag的出现主要是为了解决几个last-modifed比较难解决的问题:

1 一些文件也行会周期性的更改,可是他的内容并不改变(仅仅改变的修改时间),这个时候咱们并不但愿客户端认为这个文件被修改了,而从新GET;

2 某些文件修改很是频繁,好比在秒如下的时间内进行修改(比方说1s内修改N次)if-modified-since能检查到的粒度是s级的,这种修改没法判断(unix记录mtime只能精确到秒)

3 某些服务器不能精确获得文件的最后修改时间。

不能缓存的请求

clipboard.png

clipboard.png

相关文章
相关标签/搜索