javascript - IE 9/10/11 在某个未知阈值后不渲染图像

标签 javascript jquery html internet-explorer sharepoint

我正在构建一个从 SharePoint 2013 或 SharePoint 2010 中提取文件以在 HTML 中查看的应用程序。在 C# 中,文件从 SharePoint 中提取(多页文档,如 Word、Excel、PDF、TIFF 等),然后输入到各种第 3 方软件(DataLogics 和 Aspose)中,这些软件将文档分解为单独的页面,然后流式传输以 PNG 格式传输到浏览器的各个页面。

因此,在 HTML 中,我们有一个 img 元素,其 src 设置为 ASHX 服务中的特定 URL。 ASHX 服务从 SharePoint 中获取文件,并根据查询字符串参数,以流的形式返回所需的页面。

以下是我们如何反击:

[WebService(Namespace = "url")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FileTransfer : IHttpHandler, IReadOnlySessionState
{
    public void ProcessRequest(HttpContext context)
        var stream = GetStream(context.Request);
        int chunkSize = 2097152; //2MB
        byte[] chunk = new byte[chunkSize];
        int bytesRead = 0;

        do {
            bytesRead = stream.Read(chunk, 0, chunkSize);
            HttpContext.Current.Response.OutputStream.Write(chunk, 0, bytesRead);
        }
        while (bytesRead > 0);
}

当我们分解的文件直接来自 SharePoint 时,这在任何浏览器中都 100% 完美运行。

我们还提供了用户可以上传文档的功能。这就是问题所在。上传的文档不会保存在 SharePoint 中。相反,它们的数据存储在 SessionState 中,直到用户选择保存。文件上传到 ASMX 服务,然后浏览器通过上述 ASHX 请求各个页面。

文件在 ASMX 服务中上传如下:

[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
Public object Upload()
{
    var request = HttpContext.Current.Request;
    if (request.Files.Count == 1)
    {
        var uniqueId = request["uniqueId"];
        var file = request.Files[0];

        using (var memoryStream = new MemoryStream())
        {
            file.InputStream.CopyTo(memoryStream);
            docInfo = UploadItem(uniqueId, pageNum, memoryStream.ToArray());
        }
    }
}

UploadItem 将 uniqueId 和 byte[] 添加到 SessionState。

文件是这样从 javascript 发送的(FileUpload 与 type=file 输入的更改事件绑定(bind)):

this.FileUpload = function (files) {
    var upload = new XMLHttpRequest();
    upload.onreadystatechange = () => {
        if (this._curUploadRequest.readyState == 4) {
            // handle response
        }
    };

    UpdateFormDigest((<any>window)._spPageContextInfo.webServerRelativeUrl,(<any>window)._spFormDigestRefreshInterval);

    var data = new FormData();
    data.append("uniqueId", uniqueId);
    data.append("pageNum", pageNum);
    data.append("data", files[0]);

    upload.open('POST', "myurl");
    upload.setRequestHeader("X-RequestDigest", $("#__REQUESTDIGEST").val());
    upload.send(data);
};

现在我们来看看实际的错误。

图像使用以下方式渲染:

<img src="url to ASHX service" />

在 FireFox 和 Chrome 中,上传文档中的页面图像始终显示得很好。但在 IE(9、10 或 11)中,它仅呈现其中的第一部分,然后在图像占位符上显示损坏的图像图标。对于这些损坏的图像,IE 的 NET 选项卡显示它收到了 0kb,并且发生了错误事件。但是,如果我在 ASHX 返回流之前在 ASHX 中放置一个断点,它总是有一个大小。

更有趣的是,如果你获取 src 指向的 url,打开一个新窗口并将其粘贴进去,图像就会正常显示。

我什至尝试先像这样在 JavaScript 中加载图像:

var img = new Image();
img.onload = function(){
   // use jquery to append image to page
};
img.src = "url to ASHX service";

在这种情况下,Chrome 和 Firefox 工作正常,但 IE 再次出现故障。除此之外,IE 的 NET 选项卡显示它收到了正确大小的 kb 响应。但是,它仍然显示损坏的图像图标,并且在某个未知阈值后不会将图像渲染到屏幕上。前几张图像会恢复,但一旦其中一张损坏,其余所有图像都会损坏。

我还修改了ASHX服务以返回base64数据而不是流,然后将base64绑定(bind)到src。在调试器中,您可以看到分配给显示损坏图像图标的 img 元素的 src 的 base64。所以数据肯定是存在的,但 IE 只是不渲染它......

我尝试使用knockout JS 在这个 fiddle 中在我们的SharePoint 环境之外重新创建这个问题。基本上,我会抓取大量大图像,然后通过每次单击按钮将它们扔到屏幕上。但效果很好。如果我也使用 jQuery,它会完美地工作。

http://jsfiddle.net/bsdez92f/

不知道从这里去哪里。

有什么想法吗?

最佳答案

事实证明,图像大小导致了问题。我在服务器端将图像缩小到缩略图大小并将其返回到浏览器。此时一切工作正常。

关于javascript - IE 9/10/11 在某个未知阈值后不渲染图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30858132/

相关文章:

javascript - 导入/导出名称冲突解决

php - 使用 jquery 和 ajax 淡入 mysql 数据 1 by 1

javascript - 如何删除 Next.js block

php - 如何使用 javascript 发布表单变量,就像类型 ="submit"按钮一样

jquery UI通过UI/Effects/Transfer动态传输img

html - 在视频上制作响应式文本时遇到问题

asp.net-mvc-3 - 在 MVC3 中扩展不显眼的 javascript 以向 div 客户端添加样式的最佳方法

PHP 和 MySQL 形式,我做错了什么?

javascript - 当我从 Firebase 获取数据时,我的 Html 页面显示 [object Object]

javascript - 使用 jQuery 清理代码注入(inject)