如果你使用继承 IHttpAsyncHandler 的 WebHandler,你应该不会注意到在未确定的特定情况下浏览器 MS IE6 不会显示它,请求永远不会完成。有解决办法吗?
2 回答
我会自己回答,但是当我第一次遇到这个问题时,我花了 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”标头(我不记得是哪个)
HTTP 规范概述了客户端应如何确定请求的长度(特别是在不使用 content-length 时)。IIRC,如果内容长度标头不存在,并且响应没有分块,则在连接关闭时检测到请求的结束(这可能表明保持活动行为发生变化的原因 - 你不能使用 keep -alive 如果连接生命周期用于指示请求长度)。不过,我希望 ASP.NET 能够自动处理这个问题。也许您缺少一些调用来告诉 ASP.NET 响应已完成。
似乎生成整个内容以便您可以在异步之前添加 content-length 标头首先破坏了使用异步 HttpHandler 的目的。