2009-07-03 34 views
5

私は非常に奇妙な問題を抱えています。誰かに答えがあることを本当に願っています。Internet Explorer 8 + Deflate

私はApacheで実行され、HTMLコードを出力するC++アプリケーションをC++で作成しています。 Webホストは何らかの理由でmod_deflateをサポートしていないので、私は自分のC++アプリケーション内からHTML出力を圧縮しています。

Firefox 2、Firefox 3、Opera 9、Opera 10、Google Chrome、Safari、IE6、IE7、IE8、さらにはwgetでテストしたところ、IE8を除いてANYTHINGと動作します。

IE8では「Internet Explorerはウェブページを表示できません」という情報はまったくありません。私はそれが無効にすると動作するため、圧縮のためだと分かっています。

私が間違っていることを知っていますか?

私はそれを圧縮するためにはzlibを使用し、正確なコードがある

:彼らは非常に近いですが、といくつかの微妙な違いがあります... gzipの

/* 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では動作しますが、他のブラウザでも動作します: コンテンツエンコーディングエラー 無効またはサポートされていない形式を使用しているため、表示しようとしているページを表示できません。圧縮。 –

+1

さらに試してみると... gzipとしてコンテンツエンコーディングを送ると(それは収縮しています!)インターネットエクスプローラではie8を含むどのバージョンでも動作しますが、他のブラウザでは動作しません。もし私がdeflateを送ったら、正しいもの、それはie6とie7を含むどんなブラウザでも動作しますが、ie8ではありません。< –

+0

ユーザエージェントの検出を実行するように見えます。はい、それは醜いハックですが、私の限られた経験では、ウェブ開発はそれらでいっぱいです。 –

答えて

5

と方法は同じではありませんデフレートヘッダーなので、コンテンツエンコーディングを変更する場合は、パラメータをエンコーディング方法(具体的にはウィンドウサイズ)に変更する必要があります。

参照: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) 

およびコンテンツエンコーディングとして "GZIP" を使用

+2

うわー、ありがとう!私はあなたを愛しています:D少しの訂正。 zlibは、私が使用していたもので、「収縮した」と思っていたもの、収縮したもの、gzipです。あたかも混乱しないかのように、3つすべてが明らかにライブラリzlibを使用して作成されています。 windowBitsを指定しないと(私がやっていたように)、負の値を使ってzlib形式が出力されます(gzipではなく** DEFLATED **形式を出力します)。私はgzip形式を出力する方法がまだわかりません(そして、私は気にしません。今はすべてのブラウザで収縮しています)。再度、感謝します!! :) –

+0

+1、素敵な発見!恐らく、mod_gzipのバグです。 –

5

私は、私は私自身のHTTPサーバ、私は私自身のdeflateアルゴリズムを書いてきたように、この上で発見したものを明確にしたかった、と私の失望にIE8はまた私の収縮した内容を認識するために失敗しました:

HTTPのRFCがありますhttp://www.faqs.org/ftp/rfc/rfc2616.pdf。 HTTPヘッダーでデフレートを実行するときは、RFC 1950とRFC 1951の両方のステートが使用されます。 RFC 1950は単にヘッダとトレーラのバイトを定義しています。 deflateアルゴリズムはRFC 1951で定義されています。これをspecにプログラムすると、IE8は失敗しました。

私はRFC 1950を無視し、RFC 1951のみを実行しました。

私は、IE8がRFC 2616のページ17に正しく従っていないと仮定し、他のブラウザはどちらのフォーマットも受け入れることができます。

+0

私は、顧客のWebキャッシングプロキシを見つけただけで、それは収縮を強要していて、どの実装を選択したのか推測しています。間違ったもの、おそらくIE8をサポートする。残念ながら、標準のHTTPライブラリを使用しているJavaクライアントは、正しいdeflate実装を期待しています。私はクライアントの収縮サポートをオフにし、gzipを使うか何もしなくてはなりません。 –

関連する問題