Messages sent between Script content and the man page are JSON-serialized.
If you want to pass an ArrayBuffer object through a JSON-serialized pipe, wrap the buffer in the view before and after the transfer.
I am showing an isolated example, so the solution is usually applicable, and not just in your case. This example shows how to pass ArrayBuffer and typed arrays, but this method can also be applied to File and Blob objects using the FileReader API.
// 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
This solution has been successfully tested in Chrome 18 and Firefox.
new Uint8Array(xhr.response) used to create an ArrayBuffer so that individual bytes can be read.Array.apply(null, <Uint8Array>) used to create a simple array using the keys from the Uint8Array . This step reduces the size of the serialized message. A WARNING. This method only works for small amounts of data. When the size of the typed array exceeds 125836, a RangeError will be thrown. If you need to process large pieces of data, use other methods to convert between typed arrays and arrays.
At the end of the receiver, the source buffer can be obtained by creating a new Uint8Array and reading buffer .
Implementation of the Google Chrome extension:
// 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;
Documentation
Rob w
source share