Extension Chrome: comment passer ArrayBuffer ou Blob à partir du contenu du script à l'arrière-plan sans perdre son type?
J'ai ce contenu script qui télécharge des données binaires à l'aide XHR, qui est envoyé au plus tard à l'arrière-plan de script:
var self = this;
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status == 200) {
self.data = {
data: xhr.response,
contentType: xhr.getResponseHeader('Content-Type')
};
}
};
xhr.send();
... later ...
sendResponse({data: self.data});
Après réception de ces données en arrière-plan script, je voudrais former une autre demande XHR qui télécharge ce fichier binaire des données sur mon serveur, donc je n':
var formData = new FormData();
var bb = new WebKitBlobBuilder();
bb.append(data.data);
formData.append("data", bb.getBlob(data.contentType));
var req = new XMLHttpRequest();
req.open("POST", serverUrl);
req.send(formData);
Le problème est que le fichier téléchargé vers le serveur contient cette chaîne: "[object object]". Je suppose que cela se produit parce que ArrayBuffer type est un peu perdu pendant le transfert à partir du contenu du processus à l'arrière-plan? Comment puis-je résoudre ce problème?
Vous devez vous connecter pour publier un commentaire.
Messages transmis entre un Contenu de Script et un fond de page sont au format JSON sérialisé.
Si vous voulez transférer un
ArrayBuffer
objet par l'intermédiaire d'un JSON-sérialisé canal, envelopper le tampon dans une vue, avant et après le transfert.Je montre un exemple isolé, de sorte que la solution est applicable de manière générale, et pas seulement dans votre cas. L'exemple montre comment passer autour de
ArrayBuffer
s et tableaux typés, mais la méthode peut également être appliquée àFile
etBlob
objets, à l'aide de laFileReader
API.Cette solution a été testée avec succès dans Chrome 18 et Firefox.
nouveau Uint8Array(xhr.la réponse)
est utilisé pour créer une vue de laArrayBuffer
, de sorte que chaque octet peut être lu.Array.apply(null, <Uint8Array>)
est utilisé pour créer un simple tableau, à l'aide des touches de laUint8Array
vue. Cette étape permet de réduire la taille du message avec numéro de série. Attention: Cette méthode ne fonctionne que pour de petites quantités de données. Lorsque la taille du tableau typé dépasse 125836, un RangeError sera levée. Si vous avez besoin de gérer de grands ensembles de données, utiliser d'autres méthodes pour faire la conversion entre les tableaux typés et de la plaine des tableaux.À l'récepteurs fin, le tampon d'origine peut être obtenu par la création d'un nouveau
Uint8Array
, et la lecture de latampon
l'attribut.Mise en œuvre dans votre Google Chrome extension:
Documentation
ArrayBuffer
Uint8Array
<Fonction> .appliquer
"Cela vous permet d'envoyer en une seule fois JSON-sérialisable message à partir d'un script contenu de l'extension, ou vice versa, respectivement"
Array.apply(null, new Uint8Array(xhr.response))
ne fonctionne pas pour les tampons de grandes (plus grand que 150 ko) la collecte deMaximum call stack size exceeded
erreur. Même pour les petits tampons probablement, il est mieux de passer chaînes binaires que JS tableaux.Il y a une meilleure façon de passer
Blob
(ouArrayBuffer
) entre toutes les pièces de la même extension Chrome (scripts de contenu, le fond de page et des pages ordinaires) ensuite, la création d'un ordinaire JS Tableau ou un chaîne binaire et en la passant (parfois très gros) bloc de données dans un corps de message! Rappelez-vous qu'ils sont JSONified à la fin de l'expéditeur et puis unJSONified à la fin du récepteur!Il suffit de créer et de transmettre
Objet de l'URL
:ou créer Blob d'abord à partir de ArrayBuffer:
BTW
XMLHttpRequest 2
peut renvoyer à la foisBlob
etArrayBuffer
.Notes
URL.revokeObjectURL(objectURL)
blob:
URL sera automatiquement révoquée lorsque le document est déchargé.