Передайте большой блоб или файл с расширением Chrome
Я пытаюсь написать расширение, которое кэширует некоторые большие медиа-файлы, используемые на моем веб-сайте, чтобы вы могли локально кэшировать эти файлы, когда расширение установлено:
- Я передаю URL через chrome.runtime.sendMessage к расширению (работает)
- получить файл мультимедиа через XMLHttpRequest на фоновой странице (работает)
- сохранить файл с помощью FileSystem API (работает)
- получить объект File и преобразовать его в URL с помощью URL.createObjectURL (работает)
- вернуть 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-объекты.