Internet Explorer 8 + 放气

Posted

技术标签:

【中文标题】Internet Explorer 8 + 放气【英文标题】:Internet Explorer 8 + Deflate 【发布时间】:2009-07-03 05:18:26 【问题描述】:

我有一个非常奇怪的问题.. 我真的希望有人能回答,因为我不知道还能去哪里问。

我正在用 C++ 编写一个由 Apache 执行并输出 html 代码的 cgi 应用程序。我正在自己压缩 HTML 输出 - 从我的 C++ 应用程序中 - 因为我的网络主机由于某种原因不支持 mod_deflate。

我在 Firefox 2、Firefox 3、Opera 9、Opera 10、Google Chrome、Safari、IE6、IE7、IE8 甚至 wget 上对此进行了测试。它适用于 ANYTHING(IE8 除外)。 p>

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;

【问题讨论】:

好的,这很奇怪。如果我发送“gzip”作为内容编码,它可以在 IE8 上运行,但在任何其他浏览器上都可以使用..:内容编码错误您尝试查看的页面无法显示,因为它使用了无效或不受支持的压缩形式。跨度> 经过多次尝试.. 如果我将内容编码作为 gzip 发送(不是!它是放气),它只能在 Internet Explorer 任何版本上运行,包括 ie8,而在任何其他浏览器上都不起作用.如果我发送正确的 deflate,它适用于任何浏览器,包括 ie6 和 ie7,但不适用于 ie8 <.> 看起来是时候执行用户代理检测了。是的,这是一个丑陋的 hack,但以我有限的经验,Web 开发充满了它们。 cout = 8) ? "gzip" : "deflate"); // 好吧,这就解决了。仍然在寻找一个真正的答案,但如果有人能想出一个。 在 IE8 的 Accept-Encoding 标头中有什么线索吗? 【参考方案1】:

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)

并使用“gzip”作为内容编码

【讨论】:

哇,谢谢!我爱你 :D 稍作修正,不过。有 3 种(!)压缩格式:zlib - 我使用的一种,我认为是“deflate” -、deflate 和 gzip。好像这还不够令人困惑,它们中的所有 3 个显然都是使用库 zlib 创建的。不指定 windowBits (就像我做的那样)输出 zlib 格式,使用负值(就像你建议的那样)输出 DEFLATED 格式(不是 gzip!)。我还不确定如何输出 gzip 格式(我不在乎,现在它可以在所有浏览器上使用 deflate)。再次感谢!! :)【参考方案2】:

我想澄清一下我在这方面的发现,因为我已经编写了自己的放气算法、我自己的 HTTP 服务器,但令我沮丧的是,IE8 也无法识别我放气的内容:

HTTP RFC 是 http://www.faqs.org/ftp/rfc/rfc2616.pdf。第 17 页指出在 HTTP 标头中执行放气时使用 RFC 1950 和 RFC 1951。 RFC 1950 只是简单地定义了头部和尾部字节; deflate 算法在 RFC 1951 中定义。当我将其编程为规范时,IE8 失败了。

当我忽略 RFC 1950 而只做 RFC 1951 时,它通过了。

那么,我会假设 IE8 没有正确遵循 RFC 2616 第 17 页,并且所有其他浏览器都可以接受这两种格式。

【讨论】:

我刚刚遇到一个客户的 Web 缓存代理强制放气,猜猜他们选择了哪种实现方式?打错了,大概是支持IE8吧。不幸的是,我们使用标准 HTTP 库的 Java 客户端期待正确的 deflate 实现。我将不得不关闭我们客户端中的 deflate 支持,并强制他们使用 gzip 或什么都不用。 @MarcusAdams 在 zlib 中尝试 inflateInit2(&amp;strm, -MAX_WBITS) 而不是 inflateInit(&amp;strm)

以上是关于Internet Explorer 8 + 放气的主要内容,如果未能解决你的问题,请参考以下文章

为啥即使在模拟 Internet Explorer 8 文档模式时,Internet Explorer 11 也不支持条件注释?

Internet Explorer 8 上的独生子女替代方案

Internet Explorer 8 中的 CSS 伪类

PHP:如果 Internet Explorer 6、7、8 或 9

需要一个好的 Internet Explorer 6、7、8 独立版 [重复]

Windows Internet Explorer 8 是啥