HTTP--浏览器缓存

上一篇 / 下一篇  2014-11-10 15:20:51 / 个人分类:HTTP协议

一、Last-ModifiedETag

1.      客户端第一次请求资源时,服务器响应返回一个200的状态码,并在响应头带上该资源的Last-Modified(最后修改时间)ETag(请求资源关联的记号)头,客户端将该资源保存在cache中,并记录这两个属性;

2.      当客户端第二次请求同样的资源时,会在请求头带上If-Modified-SinceIf-None-Match两个头(两个头的值分别是响应中Last-ModifiedETag头的值)。服务器通过这两个头判断本地资源是否改变,未发生改变则返回304状态码,继续使用客户端缓存的资源。

3.      如果两个头的值与服务器的值不一致,证明发生变化,则重新响应资源至客户端并带上Last-ModifiedETag头,客户端将该资源保存在cache中,并记录这两个属性。

 

二、Last-ModifiedETagExpries

1. 客户端第一次请求资源时,服务器返回一个200的状态码,并在响应头中带上该资源的了Last-ModifiedETag头、Expries(缓存过期时间),客户端将该资源保存在cache中;

2. 第二次请求,先判断expries是否过期,过期了则连接源服务器,没有过期则用缓存中的资源(强制ctrl+F5刷新页面除外),返回304状态。

3. Firefox浏览器总是缓存所有页面,不管失效、不失效还是没有声明失效时间。即使缓存中声明了一个网页的实效日期是1970-01-01 08:00:00,浏览器仍然会发送该文件在缓存中的Last-ModifiedETag字段。 如果在服务器端验证通过,返回304状态,浏览器就还会使用此缓存

 

问题一:Last-ModifiedETag头为什么要同时用?

首先认识下Last-Modified的缺点:

1只能精确到秒的级别,一旦在一秒的时间里出现了多次修改,那么Last-Modified / If-Modified-Since是无法体现的;

2一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET

相比较,ETag / If-None-Match没有使用时间作为判断标准,而是使用一个特征串。EtagWeb组件的特征串告诉客户端,客户端在下次请求此Web组件的时候,会把上次服务端响应的特征串作为If-None-Match的值发送给服务端,服务端可以通过这个值来判断是否需要从重新发送,如果不需要,就简单的发送一个304状态码,客户端将从缓存里直接读取所需的Web组件。

 

问题二:请求时头带有 Expries,为什么还要带If-Modified-SinceIf-None-Match两个头?

Last- Modified标识能够节省一点带宽,但是还是逃不掉发一个HTTP请求出去,而且要和Expires一起用。而Expires标识却使得浏览器干脆连 HTTP请求都不用发,比如当用户F5或者点击Refresh按钮的时候就算对于有ExpiresURI,一样也会发一个HTTP请求出去,所 以,Last-Modified(If-Modified-Since)还是要用的,而 且要和Expires(If-None-Match)一起用。ETag也一样。

 

问题三:移除Etag

(1)    Etag不管怎么样的算法,在服务器端都要进行计算,计算就有开销,会带来性能损失。

(2)    在多资源分布在不同的服务器中,当浏览器从一台服务器上获取了原始组件,之后又向另一台服务器发起相同组件的Get请求时,ETag是不会匹配的,用户就不会收到一个304的响应,而是一个200响应以及组件的所有数据。如果只是一台服务器上寄宿网站,这不是什么问题,但是在集群服务器,则组件的下载次数可能会比必须下载的次数多得多,导致性能的下降。

(3) Etag还降低了代理缓存的效率,代理后面的用户缓存的Etag经常和代理缓存的Etag不匹配,这导致不必要的请求被发送到原始服务器。用户和代理之间不会出现304响应,而是两个200响应(一个服务器到代理,一个代理到客户端)

 

F5刷新:F5,客户端会重新请求服务器,会在请求头带上If-Modified-SinceIf-None-Match两个头。

Ctrl+F5强制刷新:客户端会重新请求服务器,就算客户端缓存有If-Modified-SinceIf-None-Match两个头,也不会带上。这样,任何Web组件都必须从服务器重新下载才能显示。


TAG:

 

评分:0

我来说两句

Open Toolbar