Chrome-Erweiterung: Wie kann man ArrayBuffer oder Blob vom Inhaltsskript an den Hintergrund übergeben, ohne seinen Typ zu verlieren?

8

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?

    
spektom 21.12.2011, 17:32
quelle

2 Antworten

15

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.

%Vor%

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 .

Implementierung in Ihrer Google Chrome-Erweiterung:

%Vor%

Dokumentation

Rob W 09.04.2012, 11:37
quelle
8

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 :

%Vor%

oder erstellen Blob zuerst von ArrayBuffer:

%Vor%

BTW XMLHttpRequest 2 kann sowohl Blob als auch ArrayBuffer zurückgeben.

Notizen

  • Objekt-URLs können eine ganze Zeit lang aktiv sein. Wenn Sie also keine Daten mehr benötigen, vergessen Sie nicht, solche URLs zu veröffentlichen, die URL.revokeObjectURL(objectURL)
  • Objekt-URLs wie jede URL unterliegen Herkunftsübergreifende Einschränkungen , aber alle Teile Ihrer Erweiterung haben natürlich denselben Ursprung.
  • Übrigens: Ich habe einen 4x-Leistungsschub erhalten, wenn ich solche URLs übergebe, anstatt die Daten selbst in meiner Chrome-Erweiterung weiterzuleiten! (Meine Daten waren ziemlich große Bilder.)
Konstantin Smolyanin 15.09.2013 16:18
quelle