Crashworks Crashworks - 1 year ago 62
Javascript Question

How can a Chrome extension save many files to a user-specified directory?

I'm working on a Chrome extension to be used as an internal tool. Its required behavior is:

  1. As a page action, enable an address bar icon when looking at certain intranet pages.

  2. when the user clicks the icon, identify all files of a certain media type (say, .jpg) on the page, and

  3. silently save them all to a directory on the user's local drive.

This question has been asked before, but the answer then was "use NPAPI", and NPAPI is now derelict.

So, what is the currently available way to achieve this? The ones I've looked at are:

  • The chrome.FileSystem API --- but this does not save files in any user-accessible location. Instead the stored files are hidden behind obfuscated names in an undocumented directory. User requires that the files be stored under their original names in an accessible directory.

  • The HTML5 download attribute, by creating a data: URL and programmatically clicking it. This pops up a "save as..." dialog for each file, which is unacceptable when there are a hundred assets on a single page. User requires that the files be downloaded without further interaction beyond the single icon click.

  • The Chrome Download API, but that is only available in the beta and dev channels. User requires this extension work with mainstream Chrome.

  • Use the Native Messaging API by creating a small .exe that simply saves a file to disk, and then pass the .jpg as a blob to it. This seems very cumbersome and I am not even sure how to reliably pass large blobs to EXEs like that.

Is there another approach I can try?

Answer Source

You've done quite a lot of research. Indeed, regular web pages cannot write to the user's filesystem without any plugins or extensions. Also, the HTML5 Filesystem API only provides access to a virtual filesystem, as you've observed.

However, you are confusing the chrome.fileSystem API with the HTML5 FileSystem API. Unlike the HTML FileSystem API, Chrome's fileSystem (app) API can directly write to the user's filesystem (e.g. ~/Documents or %USERPROFILE%\Documents), specified by the user.

This API is only available to Chrome apps, not extensions. This is not a problem, especially since you're developing an internal tool, because you can install the app and extension, and use message passing to communicate between the extension (page action) and app (file system access) (example).

About chrome.downloads: Since your extension is internal, you can probably force users to get on the beta/dev channel in order to use this API. The only limitation of this API is that the files will be saved in (a subdirectory of) the user-defined Downloads folder.

EDIT: The chrome.downloads API is now avaiable in all channels, including the stable branch (since Chrome 31).