【发布时间】:2015-06-16 03:08:00
【问题描述】:
我正在构建一个应用程序,该应用程序从 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 输入的更改事件相关联):
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 只是没有呈现它......
我尝试在这个小提琴中使用淘汰赛 JS 在我们的 SharePoint 环境之外重新创建这个问题。基本上,我会抓取大量大图像,并在每次单击按钮时将它们扔到屏幕上。但它工作得很好。如果我也使用 jQuery,它会完美运行。
不知道从这里去哪里。
有什么想法吗?
【问题讨论】:
标签: javascript jquery html internet-explorer sharepoint