Chrome-Erweiterung: wie gehen ArrayBuffer oder ein Blob von content-Skript in den hintergrund, ohne seine Art?
Habe ich das content-Skript, das downloads einige binäre Daten mit XHR, die später gesendet werden, um die hintergrund-Skript:
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});
Nach Erhalt dieser Daten im hintergrund-script, ich möchte eine andere form XHR-Anfrage, dass der Upload dieser binären Daten auf meinem server, so dass ich tun:
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);
Das problem ist, dass die Datei auf den server hochgeladen enthält nur diese Zeichenfolge: "[object object]". Ich denke, dies geschieht, weil ArrayBuffer Typ ist irgendwie verloren während der übertragung von Inhalt, Prozess in den hintergrund? Wie kann ich das lösen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nachrichten bestanden zwischen einem Content-Script und ein hintergrund-Seite JSON-serialisiert.
Wenn Sie übertragen möchten eine
ArrayBuffer
Objekt durch ein JSON-serialisiert Kanal, wickeln Sie den Puffer in einer Ansicht, vor und nach der übertragung.Zeige ich ein Isoliertes Beispiel, so dass die Lösung, die allgemein anwendbar ist, und nicht nur in Ihrem Fall. Das Beispiel zeigt, wie Sie pass um
ArrayBuffer
s und typed arrays, aber die Methode kann auch angewendet werden, umFile
undBlob
Objekte, die mithilfe derFileReader
API.Diese Lösung wurde erfolgreich getestet in Chrome 18 und Firefox.
neue Uint8Array(xhr.Reaktion)
wird verwendet, um eine Aussicht auf dieArrayBuffer
, so dass die einzelnen bytes können gelesen werden.Array.apply(null, <Uint8Array>)
wird verwendet, um zu erstellen ein einfaches array übergeben werden, indem Sie die Tasten derUint8Array
anzeigen. Dieser Schritt reduziert die Größe der serialisierten Nachricht. WARNUNG: Diese Methode funktioniert nur für kleine Datenmengen. Wenn die Größe des typisierten Arrays überschreitet, 125836, wird ein RangeError geworfen. Wenn Sie behandeln müssen große Teile der Daten, verwenden andere Methoden, um die Konvertierung zwischen typisierten arrays und einfachen arrays.Beim Empfänger Ende, die original-Puffer kann erhalten werden, indem erstellen Sie eine neue
Uint8Array
, und das Lesen derbuffer
- Attribut.Umsetzung in Ihrem Google-Chrome-Erweiterung:
Dokumentation
ArrayBuffer
Uint8Array
<Funktion> .apply
"Dies ermöglicht Ihnen, senden Sie ein one-time - JSON-serialisiertes Nachricht von einem content-script-Erweiterung, oder Umgekehrt, bzw."
Array.apply(null, new Uint8Array(xhr.response))
funktioniert nicht bei großer Puffer (größer als 150Kb) ErhöhungMaximum call stack size exceeded
Fehler. Auch für kleine Puffer wahrscheinlich ist es besser, pass Binär-strings, die JS-arrays.Gibt es einen besseren Weg, um pass
Blob
(oderArrayBuffer
) zwischen Teile die gleichen Chrome-Erweiterung (Inhalte, Skripte, hintergrund-page und gewöhnlichen Webseiten) dann die Erstellung einer gewöhnlichen JS Array oder eine Binär-string und die Weitergabe dieser (manchmal sehr große) Menge Daten in einem message-body! Denken Sie daran, dass Sie JSONified beim Absender Ende und dann unJSONified beim Empfänger!Erstellen Sie einfach und pass
Objekt-URL
:erstellen oder Blob ersten von ArrayBuffer:
BTW
XMLHttpRequest 2
zurückkehren können sowohlBlob
undArrayBuffer
.Hinweise
URL.revokeObjectURL(objectURL)
blob:
URL wird automatisch widerrufen, wenn das Dokument entladen wird.