3

如果你使用继承 IHttpAsyncHandler 的 WebHandler,你应该不会注意到在未确定的特定情况下浏览器 MS IE6 不会显示它,请求永远不会完成。有解决办法吗?

4

2 回答 2

4

我会自己回答,但是当我第一次遇到这个问题时,我花了 3 天时间才解决它。

当通过“img”HTML 标记的“src”属性请求图像时,在某些情况下,浏览器 MS IE6 需要 Content-Length 来完成请求并显示结果。

同步 ASHX 生成的图像,自动包含“Content-Length”HTTP 标头,但异步版本不包含。所以当你写输出的时候,先把它写到一个内存流,读取总长度,把它写成一个HTTP头,然后把内存流写到输出。

像这样:

using (Image resizedImage = generateImage())
{
    using (MemoryStream memoryStream = new MemoryStream())
    {
        resizedImage.Save(memoryStream, ImageFormat.Jpeg);
        context.Response.AddHeader("Content-Length", memoryStream.Length.ToString());
        memoryStream.WriteTo(context.Response.OutputStream);
    }
}

我已经 tcpdump 了我的代码的同步和异步版本,我注意到它们之间还有 2 个不同之处:

1) 异步处理程序将答案分成 3 个 TCP 数据包,而不是一个。

2)同步版本使用不同的“Keep-Alive”标头(我不记得是哪个)

于 2008-12-23T17:27:40.423 回答
1

HTTP 规范概述了客户端应如何确定请求的长度(特别是在不使用 content-length 时)。IIRC,如果内容长度标头不存在,并且响应没有分块,则在连接关闭时检测到请求的结束(这可能表明保持活动行为发生变化的原因 - 你不能使用 keep -alive 如果连接生命周期用于指示请求长度)。不过,我希望 ASP.NET 能够自动处理这个问题。也许您缺少一些调用来告诉 ASP.NET 响应已完成。

似乎生成整个内容以便您可以在异步之前添加 content-length 标头首先破坏了使用异步 HttpHandler 的目的。

于 2008-12-31T19:37:36.303 回答