J'utilise XMLHttpRequest synchrone avec responseType défini sur "arraybuffer" depuis un bon moment pour charger un fichier binaire et attendre jusqu'à ce qu'il soit chargé. Aujourd’hui, j’ai eu l’erreur suivante: «Les réponses aux types de réponses de XMLHttpRequest sont synchronisées avec les mods de la fenêtre, mais n’ont plus rien.» ce qui se traduit approximativement par "L'utilisation de responseType pour XMLHttpRequest en mode synchrone dans le contexte de fenêtre (?) n'est plus prise en charge".
Est-ce que quelqu'un sait comment réparer ceci? Je ne veux vraiment pas utiliser une requête asynchrone pour quelque chose comme ça.
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.responseType = 'arraybuffer';
Fonctionne bien en chrome.
C'est un comportement correct, tel que défini dans la spécification de XMLHttpRequest :
Lorsque défini: lève un
"InvalidAccessError"
exception si le synchrone flag est défini et qu'un document XMLHttpRequest associé .
La propriété responseType
ne peut pas être définie lorsque XMLHttpRequest
n'est pas asynchrone, c'est-à-dire synchrone. Si vous définissez le troisième paramètre de open
sur false
, la demande sera synchrone .
Pour le lecteur occasionnel, si vous avez toujours besoin du comportement synchrone, vous pouvez télécharger votre contenu sous forme de chaîne, puis le convertir en données d'octet.
NOTA:
Cette solution de contournement suppose que le request.response
d'origine est un texte ASCII
.
Si cette hypothèse ne correspond pas à votre cas d'utilisation spécifique, veuillez consulter jBinary .
Je le convertis en 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;
}
Si vous avez la chance de pouvoir contrôler le point d’entrée de la page entière, envisagez d’envelopper le tout avec une fonction async
et d’utiliser await
pour bloquer le code asynchrone problématique. Peut ne pas fonctionner avec tous les cas d'utilisation cependant.
(async function () {
await problem_function_1();
await problem_function_2();
... normal page logic pasted here ...
})();
Enveloppez le code asynchrone qui n'est pas une promesse avec une Promise
(afin que wait fonctionne comme prévu), puis appelez la fonction de résolution manuellement dans tout ce qui constitue un "rappel de réussite". Faites de même pour rejeter si possible.