2009-07-03 17 views
5

У меня очень странная проблема. Я действительно надеюсь, что у кого-то есть ответ, потому что я не знаю, где еще спросить.Internet Explorer 8 + Deflate

Я пишу приложение cgi на C++, которое выполняется Apache и выводит код HTML. Я сам сжимаю вывод HTML - из моего приложения на C++, поскольку по какой-то причине мой веб-хост не поддерживает 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, но в любом другом браузере.: Ошибка кодирования содержимого Страница, которую вы пытаетесь просмотреть, не может быть показана, поскольку она использует недопустимую или неподдерживаемую форму сжатия. –

+1

После нескольких попыток. Если я отправлю кодировку контента как gzip (это не так, она дефлятирована), она работает в Internet Explorer только с любой версией, включая ie8, пока она не работает ни в одном другом браузере. Если я отправлю дефлят, правильный, он работает на любом браузере, включая ie6 и ie7, но не на ie8 <. < –

+0

Похоже, пришло время выполнить обнаружение пользовательского агента.Да, это уродливый взлом, но в моем ограниченном опыте веб-разработка полна их. –

ответ

5

GZIP и выкачать методы не то же самое ... они очень близки, но есть некоторые тонкие различия с заголовок, поэтому, если вы измените кодировку содержимого, вы также должны изменить свои параметры на метод кодирования (в частности, размер окна)!

См: 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 Небольшая коррекция. Есть 3 (!) Формата сжатия: zlib - тот, который я использовал, который, как я думал, был «deflate» -, deflate и gzip. Как будто это не слишком запутывало, все 3 из них, по-видимому, созданы с использованием библиотеки zlib. Не указывая, что windowBits (как я делал) выводит формат zlib, используя отрицательное значение (как вы сказали) выводит ** формат DEFLATED ** (а не gzip!). Я еще не уверен, как вывести формат gzip (и мне все равно, теперь он работает с deflate во всех браузерах). ЕЩЕ РАЗ СПАСИБО!! :) –

+0

+1, приятно найти! Представьте, что ошибка в mod_gzip. –

5

Я хотел бы уточнить, что я обнаружил на этом, как я написал свой собственный алгоритм выкачать, мой собственный сервер HTTP, и к моему ужасу IE8 также не распознает спущенное содержание:

HTTP RFC является http://www.faqs.org/ftp/rfc/rfc2616.pdf. В заявлении указывается, что RFC 1950 и RFC 1951 используются при выполнении дефляции в заголовках HTTP. RFC 1950 просто определяет байты заголовка и трейлера; алгоритм дефляции определен в RFC 1951. Когда я запрограммировал это на spec, IE8 потерпел неудачу.

Когда я проигнорировал RFC 1950 и только сделал RFC 1951, он прошел.

Я бы предположил, что IE8 не соответствует правилу RFC 2616 стр. 17, и все другие браузеры достаточно хороши, чтобы принять любой формат.

+0

Я только что наткнулся на прокси-сервер кэширования в Интернете, который заставляет дефлировать и угадывает, какую реализацию они выбрали? Неверный, возможно, для поддержки IE8. К сожалению, наш Java-клиент, используя стандартные библиотеки HTTP, ожидает правильной реализации сползания. Мне нужно отключить поддержку дефляции в нашем клиенте и заставить их использовать gzip или ничего. –

Смежные вопросы