【问题】
代理环境数据流:本地浏览器——代理服务器(squid)——远程服务器(RS)
squid3做了缓存配置之后,IE浏览器始终无法获取squid中的缓存数据。
要解决这个问题,需要很多扩展知识,如下:
1.X-Cache 与X-Cache-Lookup的值
浏览器的HTTP消息头中的这两个值可以判断获取数据的缓存情况,其中HIT表示缓存命中,MISS表示未命中缓存。
X-Cache的值表示本地浏览器获取的值是否是squid上的缓存数据。
X-Cache-Lookup的值表示squid是否缓存了这个数据。
在squid3上做了缓存设置之后,使用Chrome或者Firefox测试X-Cache 与X-Cache-Lookup均已命中。
而在IE上测试X-Cache 未命中,X-Cache-Lookup命中。
这表示虽然服务器上已经缓存了这个数据,但IE获取的数据并不是squid上的缓存数据而是RS上的原始数据。
为什么会出现这个问题,看第二个问题。
2.Expires/Cache-Control Header和Last-Modified/If-Modified-Since和ETag/If-None-Match
这两个内容太多,我们简化一下:
Expires/Cache-Control Header:控制浏览器是否直接从浏览器缓存数据还是重新发送请求到服务器取数据。
Last-Modified/If-Modified-Since和ETag/If-None-Match:浏览器发送请求到服务器后判断文件是否已经修改过,如果没有修改过就只发送一个304回给浏览器,告诉浏览器直接从自己本地的缓存取数据;如果修改过那就整个数据重新发送给浏览器。
理解这些概念我们来看第3个非常重要的理解问题:
3.本地浏览器——代理服务器(squid)——远程服务器(RS)
在这种数据流下,我们来想想工作的原理一下,本地浏览器需要获取一个url上的数据,然后将这个HTTP请求发送给squid,squid将这个HTTP请求变成自己的请求来发送给RS。然后squid获取到数据,并将这个数据返回给本地浏览器。所以我们要明确以下几个重要的概念:
1.对于RS来说,访问RS的是squid;与本地浏览器没有任何直接关联。
2.对于squid来说,HTTP请求如果返回了304,那么squid将从自身获取缓存的数据;如果HTTP请求返回200则squid要从RS上获取新的数据。
3.对于本地浏览器来说,如果HTTP返回了304,那么我获得的数据是squid缓存的数据;如果获取的是200,则表示这个数据是squid从RS上获取的新数据,然后再传递给我的,相当于是一个新数据。
明白了以上行为,在看第4个问题:
4.浏览器刷新行为
不同的浏览器的刷新行为所发送的头信息是不一样的,假定上一次服务器返回了Last_Modified和ETag。
ie刷新: 发送If-Modified-Since,If-None-Match,无 Cache-Control值。
chrome刷新: 发送 If-Modified-Since,If-None-Match, Cache-Control值为max-age=0。
firefox刷新: 发送 If-Modified-Since,If-None-Match, Cache-Control值为max-age=0。
opera刷新: 不发送 If-Modified-Since,If-None-Match,Cache-Control值为no-cache。
safari刷新: 不发送 If-Modified-Since,If-None-Match, Cache-Control值为max-age=0 。
返回我们最初的问题:
1.IE在刷新后,发送的HTTP消息头中没有cache-control值,那么HTTP发送的消息头就没有标明到底是从本地拿缓存,还是从远程重新拿数据。那么这个HTTP头会发送给squid的作为它的HTTP消息头。
2.这这种情况下,squid不管其自身有没有缓存这个数据,仍然会从RS上去获取最新的数据,然后再传递给IE。导致缓存失败。
3.虽然IE发送了If-Modified-Since,If-None-Match,可以判断是否取缓存,但因为cache-control值,squid也无法使用cache。
【解决】
reload_into_ims on (默认为off)
在squid的配置文件中,开启这个选项及可解决问题。
reload_into_ims 的意思是将client的HTTP请求中的no-cache或reload请求转变成If-Modified-Since,这样就可以判断文件是否被modified,这时squid和RS之间的数据传输仅仅是验证这个文件是否被更新或更改。如果RS返回的是文件未被更改,则直接由squid的cache文件返回给client,如果更改了,再到RS去获取最新的文件并缓存下来,留做下一次缓存使用。
我们可以看到这个选项最对应opera的解决方案。
虽然reload_into_ims只表明可以解决no-cache的问题,但实际的测试过程中可以解决无cache-control的问题,所以也解决了IE的问题。
原文地址:http://blog.csdn.net/apache0554/article/details/46042899