共计 2652 个字符,预计需要花费 7 分钟才能阅读完成。
【 问题 】
代理环境数据流:本地浏览器——代理服务器(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 的问题。
配置 Squid 代理 http 和 rsync http://www.linuxidc.com/Linux/2013-05/84642.htm
Squid:实现高速的 Web 访问 http://www.linuxidc.com/Linux/2013-04/83512.htm
CentOS 6.2 编译安装 Squid 配置反向代理服务器 http://www.linuxidc.com/Linux/2012-11/74529.htm
简单配置 Squid 代理和反向代理 http://www.linuxidc.com/Linux/2014-04/99465.htm
CentOS 6.4 下 DNS+Squid+Nginx+MySQL 搭建高可用 Web 服务器 http://www.linuxidc.com/Linux/2014-04/99984.htm
Linux 下配置 Squid 代理服务器 http://www.linuxidc.com/Linux/2015-05/118085.htm
Squid 的详细介绍 :请点这里
Squid 的下载地址 :请点这里
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2015-05/118125.htm