コンテンツスクリプトとバックグラウンドページの間で受け渡されるメッセージはJSONでシリアル化されます。
JSONでシリアル化されたチャネルを介してオブジェクトを転送する場合は、ArrayBuffer
転送の前後にバッファーをビューでラップします。
孤立した例を示します。これにより、ソリューションは、あなたの場合だけでなく、一般的に適用可能になります。この例は、sと型付き配列を渡す方法を示していますが、 APIを使用して、このメソッドをオブジェクトにArrayBuffer
適用することもできます。File
Blob
FileReader
// In your case: self.data = { data: new Uint8Array(xhr.response), ...
// Generic example:
var example = new ArrayBuffer(10);
var data = {
// Create a view
data: Array.apply(null, new Uint8Array(example)),
contentType: 'x-an-example'
};
// Transport over a JSON-serialized channel. In your case: sendResponse
var transportData = JSON.stringify(data);
//"{"data":[0,0,0,0,0,0,0,0,0,0],"contentType":"x-an-example"}"
// At the receivers end. In your case: chrome.extension.onRequest
var receivedData = JSON.parse(transportData);
// data.data is an Object, NOT an ArrayBuffer or Uint8Array
receivedData.data = new Uint8Array(receivedData.data).buffer;
// Now, receivedData is the expected ArrayBuffer object
このソリューションは、Chrome18とFirefoxで正常にテストされています。
new Uint8Array(xhr.response)
のビューを作成するために使用されるためArrayBuffer
、個々のバイトを読み取ることができます。
Array.apply(null, <Uint8Array>)
ビューのキーを使用して、プレーン配列を作成するために使用されますUint8Array
。この手順により、シリアル化されたメッセージのサイズが縮小されます。警告:この方法は、少量のデータに対してのみ機能します。型指定された配列のサイズが125836を超えると、RangeErrorがスローされます。大量のデータを処理する必要がある場合は、他の方法を使用して、型付き配列とプレーン配列の間の変換を実行します。
受信側では、新しいバッファを作成し、Uint8Array
buffer
属性を読み取ることで、元のバッファを取得できます。
Google Chrome拡張機能での実装:
// Part of the Content script
self.data = {
data: Array.apply(null, new Uint8Array(xhr.response)),
contentType: xhr.getResponseHeader('Content-Type')
};
...
sendResponse({data: self.data});
// Part of the background page
chrome.runtime.onMessage.addListener(function(data, sender, callback) {
...
data.data = new Uint8Array(data.data).buffer;
ドキュメンテーション