XHR响应类型"ms-stream"在IE Mobile/Windows Phone 8.1上失败

17

我正在尝试在JavaScript中流式传输大量二进制数据,并在下载完成之前访问数据。在大多数主流浏览器中,我可以使用 charset=x-user-defined 技巧,在 progress 事件期间手动获取原始字节数据。

然而,在Internet Explorer中,这个技巧不起作用,我只能使用 VBArray(responseBody).toArray() 方法,这是非常慢的。不过,由于我只需要支持IE 11及更高版本,我应该能够利用IE的MSStream逐步获取数据。以下代码在IE 11桌面版上可以正常工作,但在运行IE 11移动版的Lumia Windows Phone 8.1设备上却不能:

var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'ms-stream';
xhr.onreadystatechange = function () {
    if (xhr.readyState === 3 && xhr.status === 200) {
        // reader is an MSStreamReader object
        reader.readAsArrayBuffer(xhr.response);
    }
};
xhr.send();

在Windows Phone设备上,readyState永远不会超过1,status为0,表示发生了未知错误,即使没有实际错误被抛出。

有没有人知道为什么这对我不起作用,或者可能有解决方法?


@shotgun页面和数据在桌面和手机上完全相同,我已经分别进行了小型测试,并得到了相同的结果。 - Andy E
你通过 url 请求的是什么类型的资源?该资源是否内置了浏览器检测功能?如果是这样,从我进行过的一些简单的谷歌搜索中看来,Windows 8+ 和 IE10/11 Mobile 似乎与浏览器检测脚本不兼容。 - Shotgun Ninja
@AndyE 我曾经遇到过同样的问题,这与跨站点域请求有关。你使用的URL是否以任何方式访问另一个域?此外,在您测试桌面时,哪个桌面操作系统可以正常工作? - Tech Savant
@Notorious:我在Windows 7上使用IE 11进行了测试。它确实是跨域的(目标URL位于我们的CDN上),但在生产环境中,它不会是跨域的。如果你是对的,并且它适用于同源请求,那么我可以接受测试中看到的缓慢速度。我将在生产环境中运行一些测试,并告诉你结果。 - Andy E
如果您正在运行Apache并可以设置mod_proxy在服务器上创建反向代理,则可能有效。我记得尝试过的其他事情包括cors,jsonp,document.domain,window.postmessage,我尝试了太阳下的所有东西,有些东西修复了它。可恶我的记忆力。我现在正在浏览我的代码存档,试图找到那段代码。 - Tech Savant
显示剩余14条评论
1个回答

2
假设您已经尝试了同源策略的解决方案,并且相当确定问题与同源策略无关...我认为问题是IE没有读取到状态3,因为它直到整个响应被接收才会得到状态3。
解决此问题的一种方法是在响应流的顶部发送一个两千字节的“序言”——我的测试只发送了2kb的空格。在接收到初始块之后,每次从网络接收到后续块时都会触发onprogress事件。
另外,您尝试过这个吗...
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onreadystatechange = function () {
    if (xhr.status === 200) {
        var blob = this.response;
        reader.readAsArrayBuffer(blob);
    }
};
xhr.send();

不幸的是,它仍然不能用于同一域请求。在函数表达式末尾使用分号是正确的(因为它是一个表达式),大多数代码检查工具会提示你缺少分号。目前我正在使用Comet流方法,但获取原始字节的唯一方法是使用以下技巧:new VBArray(xhr.responseBody).toArray()。这对于每个进度事件转换为ArrayBuffer是必需的,并且随着下载的数据越来越多,速度会变慢。 - Andy E
@AndyE,你可以尝试使用blob类型的另一种方法。 - Tech Savant
status 属性始终为 0,所以也行不通。我调查此问题的越多,就越确信 Windows Phone 8.1 存在一个 bug,阻止了“ms-stream”作为 XHR 值的 responseType 可用。 - Andy E
好的,如果你将它改成blob,你可能会更加幸运。另外,在桌面Win 8.1下使用IE进行测试,你可能也会发现它在那里也有问题。 - Tech Savant
当我遇到WinPhone 8.1的问题时,几乎总是在桌面Win81上也会看到它们,因此如果您在桌面Win81上没有看到它们,则可能是关于WinPhone的错误。 - Tech Savant
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接