Передайте большой блоб или файл с расширением Chrome

Я пытаюсь написать расширение, которое кэширует некоторые большие медиа-файлы, используемые на моем веб-сайте, чтобы вы могли локально кэшировать эти файлы, когда расширение установлено:

  1. Я передаю URL через chrome.runtime.sendMessage к расширению (работает)
  2. получить файл мультимедиа через XMLHttpRequest на фоновой странице (работает)
  3. сохранить файл с помощью FileSystem API (работает)
  4. получить объект File и преобразовать его в URL с помощью URL.createObjectURL (работает)
  5. вернуть URL на веб-страницу (ошибка)

К сожалению, URL не может быть использован на веб-странице. Я получаю следующую ошибку:

Не разрешается загружать локальный ресурс: blob:chrome-extension%3A//hlcoamoijhlmhjjxxxbl/e66a4ebc-1787-47e9-aaaa-f4236b710bda

Каков наилучший способ передать большой файловый объект из расширения на веб-страницу?

2 ответа

Решение

Ты почти там.

После создания blob: -URL на фоновой странице и передача его в скрипт содержимого, не пересылайте его на веб-страницу. Вместо этого получите большой двоичный объект с помощью XMLHttpRequest, создайте новый большой двоичный объект:-URL, а затем отправьте его на веб-страницу.

// assuming that you've got a valid blob:chrome-extension-URL...
var blobchromeextensionurlhere = 'blob:chrome-extension....';
var x = new XMLHttpRequest();
x.open('GET', blobchromeextensionurlhere);
x.responseType = 'blob';
x.onload = function() {
    var url = URL.createObjectURL(x.response);
    // Example: blob:http%3A//example.com/17e9d36c-f5cd-48e6-b6b9-589890de1d23
    // Now pass url to the page, e.g. using postMessage
};
x.send();

Если в текущей настройке не используются сценарии содержимого, а, например, API-интерфейс webRequest для перенаправления запроса в кэшированный результат, другой вариант заключается в использовании URI-адресов данных (файл или большой двоичный объект можно преобразовать в URI-данные с помощью <FileReader>.readAsDataURL, URI данных не могут быть прочитаны с использованием XMLHttpRequest, но это будет возможно в будущих версиях Chrome ( http://crbug.com/308768).

Две возможности, которые я могу придумать.

1) Работать externally_connectable,

Этот метод описан в документации здесь.

Суть этого: вы можете заявить, что такая-то веб-страница может передавать сообщения на ваше расширение, а затем chrome.runtime.connect а также chrome.runtime.sendMessage будет выставлен на веб-странице.

Затем вы можете, вероятно, заставить веб-страницу открыть порт для вашего внутреннего номера и использовать его для данных. Обратите внимание, что только веб-страница может инициировать соединение.

2) Использование window.PostMessage,

Метод упоминается в документации (обратите внимание на устаревшее упоминание о window.webkitPostMessage) и более подробно описано здесь.

Насколько я могу судить по документации метода (из разных мест), вы можете передать любой объект с ним, включая BLOB-объекты.

Другие вопросы по тегам