from:http://niyunjiu.javaeye.com/blog/740812


其實(shí)這個(gè)Bug是由分兩種情況的:

1.和Nginx無(wú)關(guān),是針對(duì)CSS背景圖片的。

一般用戶(hù)不會(huì)碰到,更多的時(shí)候是開(kāi)發(fā)者將自己的IE的緩存策略從默認(rèn)的”自動(dòng)”改為“每次訪(fǎng)問(wèn)都查詢(xún)”才發(fā)生 的。特點(diǎn)是鼠標(biāo)一旦浮動(dòng)到有背景圖片的地方,IE會(huì)不顧已經(jīng)緩存的圖片,自行去服務(wù)器再次獲取圖片,造成圖片短暫消失。這個(gè)問(wèn)題比較簡(jiǎn)單,可以通過(guò)以下腳 本解決。

1 <script type=”text/javascript”>// <![CDATA[
2 try {
3 document.execCommand('BackgroundImageCache', false, true);
4 } catch(e) {}
5 // ]]></script>

2. 但是實(shí)際上更常見(jiàn)的原因是Nginx上打開(kāi)了Gzip壓縮功能。

這個(gè)是IE6 的著名Bug,早在2002年就被人詳細(xì)討論過(guò)了,在IE7中有所改進(jìn),但微軟永遠(yuǎn)也不會(huì)去修復(fù)IE6了。

根本原因是Nginx對(duì)于啟用了Gzip的http上下文,即使你在之前的配置文件里聲明過(guò) gzip_disable “MSIE [1-6].”,Nginx不再對(duì)IE6用Gzip壓縮了,但是送出的http報(bào)頭卻仍然采用了和Gzip壓縮數(shù)據(jù)包相匹配的Vary: Accept-Encoding。IE6不認(rèn)識(shí)這個(gè)報(bào)頭,IE6對(duì)除了Vary: User-Agent的報(bào)頭外,都不查詢(xún)緩存,直接去服務(wù)器申請(qǐng)。更絕得是,不是使用查詢(xún)文件是否更新,而是強(qiáng)行要求一份完整文件。(IE7總算客氣了 點(diǎn),就是先查詢(xún)一下文件是否更新在下載,減輕了這個(gè)bug的影響)。

這個(gè)Bug的級(jí)別很高,靠前面1中的方法是不行的。在 NGINX中,通過(guò)add-header Cache-Control “post-check:3600, pre-check:43200″; ,象這里 介紹的方法, 也是不行的。通過(guò)一番痛苦的摸索,才發(fā)現(xiàn)要解決這個(gè)Bug,有兩個(gè)方法,一個(gè)是使用Nginx的headers-more-nginx-module, 遇到User-Agent是IE6(或者不管三七二十一),修改報(bào)頭為Vary: User-Agent。不過(guò)這個(gè)模塊并不是標(biāo)準(zhǔn)配置,需要重新編譯Nginx。

另一個(gè)更為簡(jiǎn)便易行的方式就是在諸如圖片和CSS,JS文件存取的地方加上一下語(yǔ)句,顯示關(guān)閉Gzip,并手工加上報(bào)頭。

1 if ($http_user_agent ~ “MSIE [1-6].”) {
2 #Must explicitly turns off gzip to prevent Nginx set Vary:Accept-Encoding
3 #which will prevent IE6 from caching anything
4 gzip off;
5 add_header Vary “User-Agent”;
6 }
經(jīng)過(guò)我的測(cè)試這樣是可以解決問(wèn)題的。這里只能用$http_user_agent來(lái)獲取瀏覽器參數(shù),曾經(jīng)試過(guò)$ancient_browser,不 過(guò)沒(méi)有成功。

另外,Nginx本身是有一個(gè)Gzip的Derective來(lái)控制Header的, 就是gzip_vary。設(shè)成gzip_vary off應(yīng)該也能解決問(wèn)題,但這是這個(gè)參數(shù)只能存在與http, location,server這些上下文里,不能添加到if上下文里,所以只能用gzip off; 把gzip完全給關(guān)了。