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

出处:http://www.oschina.net/question/1395553_175941

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

6月14日上海 OSC 源创会开始报名,送机械键盘和开源无码内裤

想请教一下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的优先级最高,但是并不确定。

Feng_Yu Feng_Yu
发帖于 8个月前
3回/1985阅
标签: HTTP
  • 举报 
  • | 分享到
0 收藏(3)

按票数排序  显示最新答案  共有3个答案 (最后回答: 1周前)

1
魏涛

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

--- 共有 1 条评论 ---
  • Feng_Yu@ 没有成功,补充回复看楼下。 (8个月前)  
评论(1)| 引用此答案| 举报 (2014-10-19 02:22)
0
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),望不吝赐教。

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


你可能感兴趣的:(HTTP前端)