it-swarm.com.de

Setzen von XMLHttpRequest.responseType plötzlich verboten?

Ich verwende seit einiger Zeit synchrones XMLHttpRequest, wobei responseType auf "arraybuffer" gesetzt ist, um eine Binärdatei zu laden und zu warten, bis sie geladen ist. Heute habe ich diesen Fehler erhalten: "Die Verwendung des responseType-Attributes von XMLHttpRequest wird im synchronen Modus im Windows-Kontekt nicht mehr unterstützt." was ungefähr bedeutet, dass die Verwendung von responseType für XMLHttpRequest im synchronen Modus im Fensterkontext (?) nicht mehr unterstützt wird.

Weiß jemand, wie man das behebt? Ich möchte wirklich keine asynchrone Anfrage für so etwas verwenden.

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

Funktioniert gut in Chrom.

18
Markus

Dies ist das richtige Verhalten, wie in der Spezifikation von XMLHttpRequest definiert:

Wenn gesetzt: Löst eine "InvalidAccessError" Ausnahme aus, wenn synchron flag gesetzt ist und ein zugehöriges XMLHttpRequest-Dokument vorhanden ist.

Die Eigenschaft responseType kann nicht festgelegt werden, wenn die XMLHttpRequest nicht asynchron, dh synchron ist. Das Setzen des dritten Parameters von open auf false bewirkt, dass die Anforderung synchron ist.

12
Rob W

Workaround

Wenn Sie als Gelegenheitsleser weiterhin das Synchronverhalten benötigen, können Sie den Inhalt als Zeichenfolge herunterladen und dann in Byte-Daten konvertieren

NOTA:
Diese Problemumgehung setzt voraus, dass der ursprüngliche request.response eine ASCII ist.
Wenn diese Annahme nicht zu Ihrem speziellen Anwendungsfall passt, lesen Sie bitte jBinary .

Ich konvertiere es in eine 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;
}

Mehr lesen

Verweise

8
Stephan

Wenn Sie das Glück haben, die Kontrolle über den Einstiegspunkt der gesamten Seite zu haben, sollten Sie erwägen, das Ganze mit einer Funktion async zu verpacken und await zu verwenden, um problematischen asynchronen Code zu blockieren. Funktioniert jedoch möglicherweise nicht mit allen Anwendungsfällen.

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

Brechen Sie asynchronen Code, der kein Versprechen ist, in eine Promise (damit das Warten wie erwartet funktioniert) und rufen Sie die Auflösungsfunktion manuell auf, was auch immer einen "Erfolgsrückruf" ausmacht. Machen Sie das Gleiche, wenn möglich, wenn Sie ablehnen.

0
ThrowawayDart