【问题标题】:Internet Explorer not properly downloading image from WCFInternet Explorer 无法从 WCF 正确下载图像
【发布时间】: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


【解决方案1】:

试试这个:

response.AddHeader("Content-Disposition", "filename=" + fileName);

【讨论】:

  • fileName 是否只是具有 png 扩展名的端点的名称?这里没有涉及实际文件,但端点在客户端显示为图像/png 文件。
  • 好的,我尝试添加该标题,但它不起作用。它仍然只下载 1.00KB 的请求,然后再发出一个,它只返回标头。我知道服务器正在为每个响应发送所有数据(我将响应输出到文件以及响应流,所以我可以确定),但 IE 认为不是。
【解决方案2】:

好的,我现在真的解决了。我现在使用的是 WebOperationContext.Current.OutgoingResponse,而不是使用 HttpContext.Current.Response。此外,我不是写入响应的输出流,而是从端点返回一个 Stream 对象,特别是我将图像保存到的 MemoryStream(在它被寻回 0 之后)。在传输完成之前,似乎没有一致的方法可以对HttpResponse 块进行写操作,因此请求总是过早结束。甚至 Firefox 也遇到了较大图像的问题。从端点函数返回 Stream 对象显然会使 WCF 等到所有数据都发送完毕后再结束请求。

【讨论】:

    猜你喜欢
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 2011-03-31
    • 2015-01-30
    相关资源
    最近更新 更多