【問題】
代理環境數據流:本地瀏覽器——代理服務器(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的問題。