Pass large blob or file from chrome extension

I try to write an extension caching some large media files used on my website so you can locally cache those files when the extension is installed:

  1. I pass the URLs via chrome.runtime.sendMessage to the extension (works)
  2. fetch the media file via XMLHttpRequest in the background page (works)
  3. store the file using FileSystem API (works)
  4. get a File object and convert it to a URL using URL.createObjectURL (works)
  5. return the URL to the webpage (error)

Unfortunately the URL can not be used on the webpage. I get the following error:

Not allowed to load local resource: blob:chrome-extension%3A//hlcoamoijhlmhjjxxxbl/e66a4ebc-1787-47e9-aaaa-f4236b710bda

What is the best way to pass a large file object from an extension to the webpage?

Answers:

Answer

You're almost there.

After creating the blob:-URL on the background page and passing it to the content script, don't forward it to the web page. Instead, retrieve the blob using XMLHttpRequest, create a new blob:-URL, then send it to the web page.

// 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();

If your current setup does not use content scripts, but e.g. the webRequest API to redirect request to the cached result, then another option is to use data-URIs (a File or Blob can be converted to a data-URI using <FileReader>.readAsDataURL. Data-URIs cannot be read using XMLHttpRequest, but this will be possible in future versions of Chrome (http://crbug.com/308768).

Answer

Two possibilities I can think of.

1) Employ externally_connectable.

This method is described in the docs here.

The essence of it: you can declare that such and such webpage can pass messages to your extension, and then chrome.runtime.connect and chrome.runtime.sendMessage will be exposed to the webpage.

You can then probably make the webpage open a port to your extension and use it for data. Note that only the webpage can initiate the connection.

2) Use window.PostMessage.

The method is mentioned in the docs (note the obsolete mention of window.webkitPostMessage) and described in more detail here.

You can, as far as I can tell from documentation of the method (from various places), pass any object with it, including blobs.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.