2009-07-03 173 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页,而且所有其他浏览器都足以接受这两种格式。