2009-07-03 218 views
5

我有一個很奇怪的問題..我真的希望有人有一個答案,因爲我不知道還有什麼要問。Internet Explorer 8 + Deflate

我正在用C++編寫一個cgi應用程序,由Apache執行並輸出HTML代碼。我從我的C++應用程序中自己壓縮HTML輸出 - 因爲我的Web主機出於某種原因不支持mod_deflate。我使用Firefox 2,Firefox 3,Opera 9,Opera 10,Google Chrome,Safari,IE6,IE7,IE8甚至wget測試了它。它與任何其他(IE8除外)一起使用。

IE8只是說「Internet Explorer無法顯示網頁」,沒有任何信息。我知道這是因爲壓縮只是因爲它可以工作,如果我禁用它。

你知道我在做什麼錯嗎?

我使用zlib壓縮它,確切的代碼是:

/* Compress it */ 
int compressed_output_size = content.length() + (content.length() * 0.2) + 16; 
char *compressed_output = (char *)Alloc(compressed_output_size); 
int compressed_output_length; 
Compress(compressed_output, compressed_output_size, (void *)content.c_str(), content.length(), &compressed_output_length); 

/* Send the compressed header */ 
cout << "Content-Encoding: deflate\r\n"; 
cout << boost::format("Content-Length: %d\r\n") % compressed_output_length; 
cgiHeaderContentType("text/html"); 
cout.write(compressed_output, compressed_output_length); 


static void Compress(void *to, size_t to_size, void *from, size_t from_size, int *final_size) 
{ 
int ret; 
z_stream stream; 

stream.zalloc = Z_NULL; 
stream.zfree = Z_NULL; 
stream.opaque = Z_NULL; 

if ((ret = deflateInit(&stream, CompressionSpeed)) != Z_OK) 
    COMPRESSION_ERROR("deflateInit() failed: %d", ret); 

stream.next_out = (Bytef *)to; 
stream.avail_out = (uInt)to_size; 
stream.next_in = (Bytef *)from; 
stream.avail_in = (uInt)from_size; 

if ((ret = deflate(&stream, Z_NO_FLUSH)) != Z_OK) 
    COMPRESSION_ERROR("deflate() failed: %d", ret); 

if (stream.avail_in != 0) 
    COMPRESSION_ERROR("stream.avail_in is not 0 (it's %d)", stream.avail_in); 

if ((ret = deflate(&stream, Z_FINISH)) != Z_STREAM_END) 
    COMPRESSION_ERROR("deflate() failed: %d", ret); 

if ((ret = deflateEnd(&stream)) != Z_OK) 
    COMPRESSION_ERROR("deflateEnd() failed: %d", ret); 

if (final_size) 
    *final_size = stream.total_out; 
return; 
} 
+0

好的,這很奇怪。如果我發送「gzip」作爲內容編碼,它在IE8上工作,但在任何其他瀏覽器上。: 內容編碼錯誤 您嘗試查看的頁面無法顯示,因爲它使用無效或不支持的形式壓縮。 – 2009-07-03 05:28:59

+1

經過多次嘗試..如果我發送的內容編碼爲gzip(不是!它是縮小的),它只適用於IE瀏覽器的任何版本,包括ie8,但它不適用於任何其他瀏覽器。如果我發送deflate,正確的,它適用於任何瀏覽器,包括ie6和ie7,但不會在ie8 <。< – 2009-07-03 05:36:16

+0

看起來是時候執行用戶代理檢測。是的,這是一個醜陋的黑客攻擊,但在我有限的經驗中,Web開發充滿了他們。 – 2009-07-03 05:43:57

回答

5

的gzip和deflate方法是不一樣的......他們都非常接近,但也有一些細微的差別與頭,所以,如果你改變你的內容編碼,你也應該改變你的參數編碼方法(具體來說,窗口大小)!

參見:http://apcmag.com/improve_your_site_with_http_compression.htm

也許是其他瀏覽器都忽略了您的內容編碼規範,做一些自動識別,但IE8是不是...

參見:http://www.zlib.net/manual.html#deflateInit2

嘗試使用:

method=Z_DEFLATED 
windowBits=-15 (negative so that the header is suppressed) 

並使用 「壓縮」 爲內容的編碼

5

我想澄清一下,我對這個發現,我已經寫了我自己的deflate算法,我自己的HTTP服務器,令我非常沮喪IE8也沒有認識到我泄了氣的內容:

HTTP RFC是http://www.faqs.org/ftp/rfc/rfc2616.pdf。在HTTP頭文件中執行deflate時,會使用RFC 1950和RFC 1951。 RFC 1950簡單地定義了頭部和尾部字節; deflate算法在RFC 1951中定義。當我將其編程爲規範時,IE8失敗。

當我忽略了RFC 1950並且只做了RFC 1951時,它通過了。

那麼我會假設IE8沒有正確遵循RFC 2616第17頁,而且所有其他瀏覽器都足以接受這兩種格式。