【发布时间】:2015-12-31 04:56:48
【问题描述】:
我有一个 WCF 服务,它提供一个端点来动态生成二维码图像。图像首先写入内存流tempStream。然后我在端点中有以下代码:
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.ClearContent();
response.ClearHeaders();
response.Buffer = false;
response.ContentType = "image/png";
response.CacheControl = "No-Cache";
response.AddHeader("Content-Length", tempStream.Length.ToString())
response.AddHeader("Accept-Ranges", "bytes");
tempStream.WriteTo(response.OutputStream);
response.Flush();
response.End();
它在 Firefox 中运行良好。如果我手动点击端点,则会下载图像,如果我将端点引用为img 标记中的src 属性,它将加载内联。但是,在 IE 中,图像不会在 img 标记中内联加载,如果我尝试手动点击端点,它会在第一次加载完整图像但随后的任何刷新(似乎直到重新启动浏览器),它只加载图像的一部分。
检查 F12 窗口中的网络选项卡后,它似乎正在从服务器下载 1.00 KB 的数据(包括标头),这意味着它获得了大约 750 KB 的图像数据。然后它向服务器发出另一个相同的请求,并且只取回没有图像数据的标头。 Content-Length 标头正确设置为图像大小; IE只是没有下载那么多。再一次,Firefox 很好。
我的同事建议我在Web.config 中将transferMode 设置为Streamed,我这样做了,但这也不起作用。如何让 IE 一次性下载整张图片?
编辑:
我应该注意,在 Visual Studio 的 IIS Express 服务器中运行 WCF 服务时,Internet Explorer 工作正常。只有当应用程序部署到 IIS 7.5 时才会出现问题。 Firefox 在这两种环境下都能正常工作。
编辑 2:
我刚刚在回复中添加了Thread.Sleep(1000),就在response.End() 之前,它解决了这个问题。 IE 现在下载整个响应并且不会尝试发出第二个请求。为什么?! response.Flush(); 应该在调用 response.End() 之前阻止请求并向客户端发出 all 数据,据我所知,response.End() 也会刷新流,因此手动调用 Flush() 是多余的.为什么显式阻塞线程一秒钟使其工作?我还应该注意,如果我不输入Thread.Sleep(1000),它仍然适用于第一个请求,因为.NET 必须在每次重新启动 AppPool 时 JIT 编译后端,这会阻止请求一定的时间,就像Thread.Sleep(1000) 所做的那样。
【问题讨论】:
-
您能否提供您在 F12 窗口中看到的第一个和第二个请求的响应标头,以及第二个请求的请求标头。另外,它是对第二个请求执行 HEAD 还是 GET ?顺便说一句,WCF 不支持接受范围。
-
我明天可以发布它们,但它们并没有什么特别之处。我使用 Accept-Ranges 作为实验,因为 IE 似乎只下载 WCF 返回的部分数据,我不确定更改 Accept-Ranges 值是否会使其想要下载整个响应。
标签: c# html image wcf internet-explorer