Ich habe dieses Inhaltsskript, das einige Binärdaten mit XHR herunterlädt, die später an das Hintergrundskript gesendet werden:
%Vor%Nachdem ich diese Daten im Hintergrundskript erhalten habe, möchte ich eine weitere XHR-Anfrage erstellen, die diese Binärdaten auf meinen Server hochlädt, also mache ich:
%Vor%Das Problem besteht darin, dass die auf den Server hochgeladene Datei nur diese Zeichenfolge enthält: "[object Object]". Ich vermute, das passiert, weil der ArrayBuffer-Typ beim Übertragen vom Inhaltsprozess in den Hintergrund irgendwie verloren geht? Wie kann ich das lösen?
Nachrichten, die zwischen einem Inhaltsskript und einer Hintergrundseite übergeben werden, sind JSON-serialisiert.
Wenn Sie ein ArrayBuffer
-Objekt über einen JSON-serialisierten Kanal übertragen möchten, müssen Sie den Puffer vor und nach der Übertragung in eine Ansicht einfügen.
Ich zeige ein isoliertes Beispiel, so dass die Lösung allgemein anwendbar ist, und nicht nur in Ihrem Fall. Das Beispiel zeigt, wie ArrayBuffer
s und typisierte Arrays weitergegeben werden, aber die Methode kann auch auf die Objekte File
und Blob
angewendet werden, indem die FileReader
API.
Diese Lösung wurde erfolgreich in Chrome 18 und Firefox getestet.
new Uint8Array(xhr.response)
wird verwendet, um eine Ansicht von ArrayBuffer
, damit die einzelnen Bytes gelesen werden können. Array.apply(null, <Uint8Array>)
wird verwendet, um ein einfaches Array mit den Schlüsseln aus der Uint8Array
-Ansicht zu erstellen. 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 125836 überschreitet, wird ein RangeError ausgelöst. Wenn Sie große Datenmengen verarbeiten müssen, verwenden Sie andere Methoden für die Konvertierung zwischen typisierten Arrays und einfachen Arrays.
Auf der Empfängerseite kann der ursprüngliche Puffer erhalten werden durch Erstellen eines neuen Uint8Array
und lesen Sie das Attribut buffer
.
ArrayBuffer
Uint8Array
<Function> .apply
Es gibt eine bessere Möglichkeit, Blob
(oder ArrayBuffer
) zwischen Teilen von derselben Chrome-Erweiterung (Inhaltsskripts, Hintergrundseiten und normale Seiten) Erstellen Sie dann eine gewöhnliche JS Array oder eine binäre Zeichenfolge und übergeben Sie diesen (manchmal extrem großen) Datenblock in einem Nachrichtentext! Denken Sie daran, dass sie am Ende des Absenders JSonified sind und dann am Ende des Empfängers unJSONified sind!
Erstellen und übergeben Sie einfach Object URL
:
oder erstellen Blob zuerst von ArrayBuffer:
%Vor% BTW XMLHttpRequest 2
kann sowohl Blob
als auch ArrayBuffer
zurückgeben.
URL.revokeObjectURL(objectURL)
Tags und Links javascript json google-chrome-extension typed-arrays xmlhttprequest-level2