简体   繁体   English

突然禁止设置 XMLHttpRequest.responseType?

[英]Setting XMLHttpRequest.responseType forbidden all of a sudden?

I've been using synchronous XMLHttpRequest with responseType set to "arraybuffer" for quite a while to load a binary file and wait until it is loaded.我一直在使用同步 XMLHttpRequest 并将 responseType 设置为“arraybuffer”很长一段时间来加载二进制文件并等待它被加载。 Today, I got this error: "Die Verwendung des responseType-Attributes von XMLHttpRequest wird im synchronen Modus im window-Kontekt nicht mehr unterstützt."今天,我收到了这个错误:“Die Verwendung des responseType-Attributes von XMLHttpRequest wird im synchronen Modus im window-Kontekt nicht mehr unterstützt。” which roughly translates to "Usage of responseType for XMLHttpRequest in synchronous mode in window-context(?) no longer supported."大致翻译为“不再支持在窗口上下文(?)中以同步模式使用 responseType for XMLHttpRequest”。

Does anyone know how to fix this?有谁知道如何解决这一问题? I realy don't want to use an asynchronous request for something like this.我真的不想对这样的事情使用异步请求。

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

Works fine in chrome.在 chrome 中工作正常。

This is correct behaviour, as defined in theSpecification of XMLHttpRequest :这是正确的行为,如XMLHttpRequest 规范中所定义:

When set: throws an "InvalidAccessError" exception if the synchronous flag is set and there is an associated XMLHttpRequest document .设置时:如果设置了 同步标志并且存在关联的XMLHttpRequest 文档,则抛出"InvalidAccessError"异常。

The responseType property cannot be set when the XMLHttpRequest is not async, that is, synchronous.XMLHttpRequest不是异步的,即同步的时,无法设置responseType属性。 Setting the third parameter of open to false causes the request to be synchronous .open的第三个参数设置为false会导致请求同步

Workaround解决方法

For the casual reader, if you still need the synchronous behavior, you can download your content as string and then convert it to byte data对于休闲读者,如果您仍然需要同步行为,您可以将您的内容下载为字符串,然后将其转换为字节数据

NOTA:备注:
This workaround assumes the original request.response is an ASCII text.此解决方法假定原始request.responseASCII文本。
If this assumption doesn't fit your specific use case please see jBinary .如果此假设不适合您的特定用例,请参阅jBinary

I convert it to an ArrayBuffer .我将其转换为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;
}

More reading更多阅读

  • jBinary : High-level API for working with binary data in Javascript. jBinary :用于在 Javascript 中处理二进制数据的高级 API。
  • Sending and Receiving Binary Data : Binary data handling with vanilla Javascript. 发送和接收二进制数据:使用 vanilla Javascript 处理二进制数据。 ( Source: Mozilla Developer Network) 来源: Mozilla 开发者网络)

References参考

As it's not possible to set responseType = 'arraybuffer' in sync mode, receiving string and converting to bytes is a solution, but as Stephan said, your data should be an ascii text.由于无法在同步模式下设置responseType = 'arraybuffer' ,因此接收字符串并转换为字节是一种解决方案,但正如 Stephan 所说,您的数据应该是 ASCII 文本。 You will receive wrong value (253) instead of all bytes above 127.您将收到错误的值 (253) 而不是 127 以上的所有字节。

But setting mime-type and charset to x-user-defined might be a solution:但是将mime-type和 charset 设置为x-user-defined可能是一个解决方案:

Here server send 10 bytes from 125 to 134:这里服务器从 125 到 134 发送 10 个字节:

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]

without setting mime-type it's like this:不设置 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]

If you're lucky enough to have control over the entry point of the whole page, consider wrapping the whole thing with an async function and using await to block on problematic asynchronous code.如果您有幸控制整个页面的入口点,请考虑使用async函数包装整个内容并使用await阻止有问题的异步代码。 Might not work with all use cases though.不过可能不适用于所有用例。

(async function () {
    await problem_function_1();
    await problem_function_2();
    ... normal page logic pasted here ...
})(); 

Wrap async code that is not a promise with a Promise (so that await works as expected), and call the resolve function manually in whatever constitutes a "success callback".Promise包装不是承诺的异步代码(以便 await 按预期工作),并在构成“成功回调”的任何情况下手动调用 resolve 函数。 Do the same for reject if possible.如果可能,对拒绝执行相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JavaScript XMLHttpRequest.responseType as &quot;arraybuffer&quot; -- 如何获取当前的数组缓冲区块 - JavaScript XMLHttpRequest.responseType as "arraybuffer" -- how to get current arraybuffer chunk 为什么在调用open throw之前设置XMLHttpRequest responseType? - Why does setting XMLHttpRequest responseType before calling open throw? new XMLHttpRequest()。responseType为空 - new XMLHttpRequest().responseType empty XMLHttpRequest的responseType属性可以接受多个值 - responseType property of the XMLHttpRequest to accept multiple values javafx webview javascript XMLHttpRequest responseType数组缓冲区 - javafx webview javascript XMLHttpRequest responseType arraybuffer 如何检测XMLHttpRequest是否支持responseType =“arraybuffer”? - How to feature detect if XMLHttpRequest supports responseType = “arraybuffer”? 用于responseType arraybuffer的xmlHttpRequest GET在电子中获得空响应 - xmlHttpRequest GET for responseType arraybuffer gets empty response in electron XMLHttpRequest responseType =“json”给出错误SYNTAX_ERR:DOM异常12 - XMLHttpRequest responseType = “json” giving error SYNTAX_ERR: DOM Exception 12 将 API 密钥设置为 XMLHttpRequest 的标头 - Setting an API key as a header for a XMLHttpRequest XMLHTTPRequest为CORS设置适当的标题 - XMLHTTPRequest Setting Proper Headers for CORS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM