IE 9/10/11在未知阈值

时间:2015-06-16 03:08:00

标签: javascript jquery html internet-explorer sharepoint

我正在构建一个从SharePoint 2013或SharePoint 2010中提取文件以便在HTML中查看的应用程序。在C#中,文件从SharePoint(Word,Excel,PDF,TIFF等多页文档)中提取出来,然后被送入各种第三方软件(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的输入的change事件):

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中放置一个断点,它总是有一个大小。

更有趣的是,如果你拿到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绑定到src。在调试器中,您可以看到分配给显示损坏图像图标的img元素的src的base64。所以数据肯定存在,但IE只是没有渲染它......

我试图在这个小提琴中使用knockout JS在我们的SharePoint环境之外重新创建这个问题。基本上,我抓住了大量的大图像,并按下每个按钮将它们扔到屏幕上。但它的工作正常。如果我也使用jQuery,它的工作原理很完美。

http://jsfiddle.net/bsdez92f/

不知道从哪里开始。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

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