突然禁止设置XMLHttpRequest.responseType?

时间:2012-03-24 20:07:01

标签: javascript ajax firefox xmlhttprequest

我一直在使用同步XMLHttpRequest,其responseType设置为“arraybuffer”很长一段时间来加载二进制文件并等到它被加载。今天,我收到了这个错误: “Die Verwendung des responseType-Attributes von XMLHttpRequest wird im synchronen Modus im window-Kontekt nichtmehrunterstützt。” 大致翻译为 “不再支持在窗口上下文(?)中以同步模式使用responseType for XMLHttpRequest。”

有谁知道如何解决这个问题?我真的不想对这样的事情使用异步请求。

var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.responseType = 'arraybuffer';

在Chrome中工作正常。

4 个答案:

答案 0 :(得分:13)

这是正确的行为,如Specification of XMLHttpRequest

中所定义
  

设置时:如果"InvalidAccessError"已设置并且存在关联的synchronous flag,则会引发XMLHttpRequest document例外。

responseType不是异步,即同步时,无法设置XMLHttpRequest属性。将open的第三个参数设置为false会导致请求同步

答案 1 :(得分:8)

解决方法

对于休闲读者,如果您仍然需要同步行为,可以将内容下载为字符串,然后将其转换为字节数据

<强> NOTA:
此解决方法假设原始request.responseASCII文本 如果此假设不适合您的特定用例,请参阅jBinary

我将其转换为ArrayBuffer

var request = new XMLHttpRequest();
request.open('GET', url, false);
request.send(null);

var data;
if (request.status === 200) {
    data = stringToArrayBuffer(request.response);
} else {
    alert('Something bad happen!\n(' + request.status + ') ' + request.statusText);
}

// ...

function stringToArrayBuffer(str) {
    var buf = new ArrayBuffer(str.length);
    var bufView = new Uint8Array(buf);

    for (var i=0, strLen=str.length; i<strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }

    return buf;
}

更多阅读

  • jBinary:用于在Javascript中处理二进制数据的高级API。
  • Sending and Receiving Binary Data:使用vanilla Javascript进行二进制数据处理。 (来源: Mozilla开发者网络)

参考

答案 2 :(得分:0)

如果您有幸可以控制整个页面的入口点,请考虑使用var _default = (0, reactLifecyclesCompat.polyfill)(Transition);函数包装整个内容,并使用async来阻塞有问题的异步代码。可能无法在所有用例中使用。

await

(async function () { await problem_function_1(); await problem_function_2(); ... normal page logic pasted here ... })(); 包装不是承诺的异步代码(以便await按预期方式工作),并以任何构成“成功回调”的方式手动调用resolve函数。如果可能,请执行相同的拒绝操作。

答案 3 :(得分:0)

由于无法将responseType = 'arraybuffer'设置为同步模式,因此接收字符串并转换为字节是一种解决方案,但是正如Stephan所说,您的数据应为ascii文本。您将收到错误的值(253),而不是所有高于127的字节。

但是将mime-type和字符集设置为x-user-defined可能是一种解决方案:

此处服务器将10个字节从125发送到134:

request = new XMLHttpRequest();
request.overrideMimeType('text/plain; charset=x-user-defined');
request.open('GET', url, false);
request.send();
Uint8Array.from(request.response, c => c.charCodeAt(0));
> Uint8Array(10) [125, 126, 127, 128, 129, 130, 131, 132, 133, 134]

没有设置mime-type就是这样:

request = new XMLHttpRequest();
request.open('GET', url, false);
request.send();
Uint8Array.from(request.response, c => c.charCodeAt(0));
> Uint8Array(10) [125, 126, 127, 253, 253, 253, 253, 253, 253, 253]