comment puis-je accéder à XHR responseBody (pour des données binaires) à partir de Javascript dans IE?
J'ai une page web qui utilise XMLHttpRequest pour télécharger une ressource binaire.
Dans Firefox et Gecko je peux utiliser responseText pour obtenir les octets, même si le bytestream comprend binaire des zéros. J'ai peut-être besoin de forcer le type mime avec overrideMimeType()
de faire que cela se produise. Dans IE, si, responseText ne fonctionne pas, parce qu'elle semble mettre fin à la première zéro. Si vous lisez 100 000 octets, et octet 7 est un zéro binaire, vous serez en mesure d'accéder à seulement 7 octets. IE XMLHttpRequest expose un responseBody
propriété pour accéder à la octets. J'ai vu quelques posts ce qui suggère qu'il est impossible d'accéder à cette propriété de manière significative, directement à partir de Javascript. Cela semble fou de moi.
xhr.responseBody
est accessible à partir de VBScript, donc, la solution évidente est de définir une méthode en VBScript dans la page web, puis appelez la méthode à partir de Javascript. Voir jsdap pour un exemple. EDIT: NE PAS UTILISER CE VBScript!!
var IE_HACK = (/msie/i.test(navigator.userAgent) &&
!/opera/i.test(navigator.userAgent));
//no no no! Don't do this!
if (IE_HACK) document.write('<script type="text/vbscript">\n\
Function BinaryToArray(Binary)\n\
Dim i\n\
ReDim byteArray(LenB(Binary))\n\
For i = 1 To LenB(Binary)\n\
byteArray(i-1) = AscB(MidB(Binary, i, 1))\n\
Next\n\
BinaryToArray = byteArray\n\
End Function\n\
</script>');
var xml = (window.XMLHttpRequest)
? new XMLHttpRequest() //Mozilla/Safari/IE7+
: (window.ActiveXObject)
? new ActiveXObject("MSXML2.XMLHTTP") //IE6
: null; //Commodore 64?
xml.open("GET", url, true);
if (xml.overrideMimeType) {
xml.overrideMimeType('text/plain; charset=x-user-defined');
} else {
xml.setRequestHeader('Accept-Charset', 'x-user-defined');
}
xml.onreadystatechange = function() {
if (xml.readyState == 4) {
if (!binary) {
callback(xml.responseText);
} else if (IE_HACK) {
//call a VBScript method to copy every single byte
callback(BinaryToArray(xml.responseBody).toArray());
} else {
callback(getBuffer(xml.responseText));
}
}
};
xml.send('');
Est-ce vraiment vrai? La meilleure façon de faire? la copie de chaque octet? Pour un grand flux binaire qui ne va pas être très efficace.
Il y a aussi un possible technique à l'aide de ADODB.Stream, qui est un COM équivalent d'un MemoryStream. Voir ici pour un exemple. Il ne nécessite pas de VBScript, mais il est séparé de l'objet COM.
if (typeof (ActiveXObject) != "undefined" && typeof (httpRequest.responseBody) != "undefined") {
//Convert httpRequest.responseBody byte stream to shift_jis encoded string
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 1; //adTypeBinary
stream.Open ();
stream.Write (httpRequest.responseBody);
stream.Position = 0;
stream.Type = 1; //adTypeBinary;
stream.Read.... ///???? what here
}
Mais qui ne va pas au travail le bien - ADODB.Flux de données est désactivé sur la plupart des machines de nos jours.
Dans La IE8 outils de développement - la d'IE équivalent de Firebug - je peux voir le responseBody est un tableau d'octets et je peux même voir les octets eux-mêmes. Les données sont là. Je ne comprends pas pourquoi je ne peux pas l'obtenir.
Est-il possible pour moi de le lire avec responseText?
conseils? (autres que la définition d'une méthode VBScript)
Vous devez vous connecter pour publier un commentaire.
Oui, la réponse m'est venu pour la lecture de données binaires via XHR dans IE, est d'utiliser VBScript injection. C'était de mauvais goût pour moi au début, mais, moi, je vois juste un navigateur plus dépendants peu de code.
(La régulière XHR et responseText fonctionne très bien dans d'autres navigateurs; vous pouvez avoir à forcer le type mime de
XMLHttpRequest.overrideMimeType()
. Ce n'est pas disponible sur IE).C'est comment j'ai obtenu une chose qui fonctionne comme
responseText
dans IE, même pour des données binaires.Tout d'abord, injecter quelques VBScript comme une chose une seule fois, comme ceci:
La JS classe que j'utilise qui lit les fichiers binaires expose une seule méthode intéressante,
readCharAt(i)
, qui lit le caractère (un octet, vraiment) à la i-ième de l'index. C'est la façon dont je l'ai installé:La le code de conversion a été fourni par Miskun.
Très rapide, fonctionne très bien.
J'ai utilisé cette méthode pour lire et extraire des fichiers zip à partir de Javascript, et aussi dans une classe qui lit et affiche des fichiers EPUB en Javascript. Très raisonnable de la performance. Environ une demi-seconde pour un fichier de 500 ko.
getBuffer
fonction. Qu'est-ce que cela? Autant que je sache, seul IE prend en chargeresponseBody
. Donc qu'avez-vous utilisé ??[]
opérateur sur les chaînes de caractères. Il utilise.charAt(num)
à la place. Donc, il n'est peut-être vous avez besoinresponseText.charAt(i)
?XMLHttpRequest.responseBody
est unVBArray
objet contenant les octets brutes. Vous pouvez convertir ces objets à la norme tableaux à l'aide de latoArray()
fonction:Je suggère deux autres (rapide) options:
Tout d'abord, vous pouvez utiliser
ADODB.Jeu d'enregistrements pour convertir le tableau d'octets en une chaîne de caractères. Je suppose que cet objet est plus commun que ADODB.Stream, qui est souvent désactivé pour des raisons de sécurité. Cette option est TRÈS rapide, moins de 30ms pour un fichier de 500 ko.
Deuxième, si le jeu n'est pas accessible, il y a un astuce pour accéder au tableau d'octets de données à partir de Javascript. Envoyer votre xhr.responseBody à VBScript, le passer à travers tout VBScript fonction de chaîne tels que CStr (ne prend pas le temps), et le retourner à la JS. Vous obtiendrez une étrange chaîne d'octets concaténés en unicode 16 bits (en sens inverse). Vous pouvez ensuite convertir cette chaîne rapidement utilisable à bytestring par le biais d'un expression régulière avec un dictionnaire de remplacement. Prend environ 1s pour 500kB.
À des fins de comparaison, l'octet-par-octet de conversion à l'aide de boucles prend plusieurs minutes pour cette même 500kB fichier, donc c'est un no-brainer 🙂 ci-Dessous le code que j'ai été en utilisant, pour les insérer dans votre en-tête. Puis appeler la fonction ieGetBytes avec votre xhr.responseBody.
Merci beaucoup pour cette solution. le BinaryToArray() fonction VbScript fonctionne très bien pour moi.
D'ailleurs, j'ai besoin de données binaires pour fournir une Applet. (Ne me demandez pas pourquoi, les Applets ne peuvent pas être utilisés pour le téléchargement de données binaires. Longue histoire courte.. bizarre MS authentification ne peux pas passer par les applets (URLConn) appels. Son particulièrement étrange dans les cas où les utilisateurs sont derrière un proxy )
L'Applet a besoin d'un tableau d'octets à partir de ces données, voici ce que j'ai à faire pour l'obtenir:
Le tableau d'octets peut ensuite converti en un bytearrayinputstream pour la poursuite du traitement.
J'ai essayé de télécharger un fichier et de le signer à l'aide de CAPICOM.DLL. La seule façon que j'petit plus ponctuellement le faire est par l'injection d'une fonction VBScript qui ne le téléchargement. C'est ma solution:
Merci pour ce post.
J'ai trouvé ce lien utile:
http://www.codingforums.com/javascript-programming/47018-help-using-responsetext-property-microsofts-xmlhttp-activexobject-ie6.html
Spécialement cette partie:
J'ai ajouté à ma page htm.
Puis-je appeler cette fonction à partir de mon javascript:
Fonctionne sur IE8, IE9, IE10, FF & Chrome.
Vous pourriez tout aussi bien faire un script de proxy qui va à l'adresse que vous demandez & base64 est tout. Ensuite vous avez juste à passer d'une chaîne de requête pour le script de proxy qui lui indique l'adresse. Dans IE vous avez à faire manuellement en base64 en JS si. Mais c'est une voie à suivre si vous ne voulez pas utiliser VBScript.
J'ai utilisé ce pour mon émulateur GameBoy Color.
Voici le script PHP qui fait la magie: