Http缓存问题分析

xiaoxiao2021-02-28  18

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) 是,正如其名,通过服务器来告知缓存是否可用

强缓存相关的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等中继缓存服务器对其缓存

 

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


协商缓存

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

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

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也就不会改变.

 

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 某些服务器不能精确得到文件的最后修改时间。

 

转载请注明原文地址: https://www.6miu.com/read-2720689.html

最新回复(0)