Сообщения, передаваемые между скриптом содержимого и фоновой страницей, сериализуются в формате JSON.
Если вы хотите передать объект ArrayBuffer
через сериализованный JSON канал, оберните буфер в представление до и после передачи.
Я показываю отдельный пример, так что решение в целом применимо, а не только в вашем случае. В примере показано, как обойти ArrayBuffer
s и типизированные массивы, но этот метод также можно применить к объектам File
и Blob
, используя 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
Это решение было успешно протестировано в Chrome 18 и 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;
Документация