HTTP缓存技术,304(Not Modified)和200(from cache)有何区别?

Feng_Yu 发布于 2014/10/18 22:09
阅读 34K+
收藏 8

想请教一下http服务器的缓存技术,也看过《http权威指南》这本书,了解过一些缓存头。

目前我的疑问就是在实际环境中配置http headers的时候,发现浏览器有的返回的是304(Not Modified),有的返回的是200(from cache),结果似乎都是成功缓存了,并未从服务器下载数据。想请教一下这两种响应究竟有何区别?是什么情况下造成了这两种响应?

另外,我还想问一下ETag,Cache-Control,Expires这几种缓存头的优先级问题,因为我发现drupal会同时返回这三种头,偶尔ETag返回头中带有一些非hash字符,比如“1413641195-gzip-gunzip”,会造成缓存失效,怎么刷新都是200 OK,后来在apache中强行屏蔽掉ETag头之后发现返回200 (from cache),缓存成功,感觉似乎是ETag的优先级最高,但是并不确定。

加载中
3
魏涛
魏涛

200是正常,304是内容没有修改。

当你第一次访问时,服务器会返回给你200状态码,同时在头里追加ETag值给你。浏览器拿到后将其缓存。

下一次再访问时,因浏览器已经有该地址的ETag值了。会将其缓存的ETag值内容放在请求头的If-None-Match中,服务器检查其自身内容的ETag值是否与其一致,如果一致就会返回304状态码,告诉你内容和你保存的一致,没有发生改变过。

举例来说,
C:S,你几岁了?
S:C,我18岁了。
===========
C:S,你几岁了?我猜你18岁了。
S:靠,你知道还问我?(304)
===========
C:S,你几岁了?我猜你18岁了。
S:C,我19岁了。(200)


以上就是200和304的解释。

Cache-Control和Expires则是告诉浏览器缓存这些数据的策略。

drupal则并非是非法hash导致的问题,问题在于gzip上。gzip其实就是gunzip了。ZIP压缩会有个特点,相同的内容重复压缩得到的二进制是不一样的,这和其字典策略相关(猜测,未验证),你可以随便压缩个文件对比2次的ZIP包checksum值是否一致来确认。那么这样就可以解释了,虽然原始内容没有改变,但是传输时因为用了gzip,所以drupal认为原始数据始终在改变,每次返回200也符合我先前所讲的内容。

最后,根据REST的原则,可以看出一些请求是幂等的,一些请求是非幂等的。那么服务器与客户端之间的缓存层,比如CDN也好,drupal,或者nginx等,都会对幂等请求做缓存策略,非幂等请求不做缓存策略。这里如何来控制,则需要服务器端在返回内容时利用好Cache-Control和Expires等头信息来进行。

最终,也是最重要的一句,这位爷,看我费了那么多口舌给你细细道来,就给我个最佳答案吧,小的在这里给爷跪下了。m(_ _)m

Feng_Yu
Feng_Yu
@ 没有成功,补充回复看楼下。
2
idoz
idoz

其实, 200 OK (from cache)  是浏览器没有跟服务器确认,直接用了浏览器缓存;而 304 Not Modified 是浏览器和服务器多确认了一次缓存有效性,再用的缓存。200(from cache) 是速度最快的,因为不需要访问远程服务器,直接使用本地缓存.304 的过程是, 先请求服务器, 然后服务器告诉我们这个资源没变, 浏览器再使用本地缓存.

结论: 需要设置 200 from cache. 这样才是解决问题之道. 

200 (cache) means Firefox is simply using the locally cached version. This is the fastest because no request to the Web server is made.

304 means Firefox is sending a "If-Modified-Since" conditional request to the Web server. If the file has not been updated since the date sent by the browser, the Web server returns a 304 response which essentially tells Firefox to use its cached version. It is not as fast as 200 (cache) because the request is still sent to the Web server, but the server doesn't have to send the contents of the file.

千斤难买春秋醉
千斤难买春秋醉
你才是正解
0
Feng_Yu
Feng_Yu

@魏涛

多谢解答,200 OK我是知道的,就是你说的200响应码的含义。但是我没理解200 OK(from cache)的含义,按理说200应该是浏览器实际从服务器下载数据了,但是200 OK(from cache)却并非如此,可以看到chrome和firefox的调试工具中network那里,显示200 OK(from cache)的size是没有的,显示(from cache),我没理解这个是怎么回事。为什么浏览器已经得到200响应码之后,依旧可以“很智能”的from cache了呢?更奇怪的是看到响应头里,浏览器带上了If-Modified-Since头,和服务端返回的Date是一样的,理论上应该响应码是304才对,为何我会得到200 OK(from cache),望不吝赐教。

水牛叔叔
水牛叔叔
回复 @Feng_Yu : 200 OK (from cache)压根就没有发送网络请求
Feng_Yu
Feng_Yu
回复 @魏涛 : 多谢,看到那个博客的解释明白了,原来drupal将这几个响应头全部带上了。apache屏蔽掉了ETag之后,还有Expires头,浏览器看到了这个头,这个头起了作用,响应了200 OK (from cache)
魏涛
魏涛
If-Modified-Since与If-None-Match之间的区别在于,前者是页面的最后修改时间,后者可以是任意属性,默认为其内容的MD5值,大部分服务是这么实现的,后者可以通过通过编码的方式来自定义之。
魏涛
魏涛
http://blog.csdn.net/joeyon1985/article/details/38729235
0
vvian00
vvian00

配不出来,基本是因为 Etag 的缘故 : 200 OK (from cache) 与 304 Not Modified 

0
slulu
slulu
试了下,图片缓存的情况多会出现304Not Modified
返回顶部
顶部