我一直在使用同步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中工作正常。
答案 0 :(得分:13)
这是正确的行为,如Specification of XMLHttpRequest:
中所定义设置时:如果
"InvalidAccessError"
已设置并且存在关联的synchronous flag,则会引发XMLHttpRequest document例外。
responseType
不是异步,即同步时,无法设置XMLHttpRequest
属性。将open
的第三个参数设置为false
会导致请求同步。
答案 1 :(得分:8)
对于休闲读者,如果您仍然需要同步行为,可以将内容下载为字符串,然后将其转换为字节数据
<强> NOTA:强>
此解决方法假设原始request.response
是ASCII
文本
如果此假设不适合您的特定用例,请参阅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;
}
答案 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]