Как расширение Chrome может сохранить множество файлов в указанный пользователем каталог?

Я работаю над расширением Chrome, которое будет использоваться как внутренний инструмент. Требуемое поведение:

  1. В качестве действия страницы включите значок в адресной строке при просмотре определенных страниц интрасети.
  2. когда пользователь нажимает на значок, идентифицирует все файлы определенного типа мультимедиа (скажем, .jpg) на странице, и
  3. молча сохранить их все в каталог на локальном диске пользователя.

Этот вопрос был задан ранее, но тогда ответ был " использовать NPAPI", и NPAPI теперь заброшен.

Итак, каков в настоящее время доступный способ достичь этого? Те, на которые я смотрел:

  • API chrome.FileSystem --- но это не сохраняет файлы в любом доступном для пользователя месте. Вместо этого сохраненные файлы скрыты за скрытыми именами в недокументированном каталоге. Пользователь требует, чтобы файлы были сохранены под их оригинальными именами в доступном каталоге.
  • Атрибут загрузки HTML5, создавая data: URL и программно щелкая по нему. Появляется диалоговое окно "Сохранить как..." для каждого файла, что недопустимо, если на одной странице есть сотни ресурсов. Пользователь требует, чтобы файлы загружались без дальнейшего взаимодействия, кроме одного щелчка значка.
  • API загрузки Chrome, но он доступен только в каналах бета и разработки. Пользователь требует, чтобы это расширение работало с основным Chrome.
  • Используйте Native Messaging API, создав небольшой.exe-файл, который просто сохраняет файл на диск, а затем передает.jpg в виде большого двоичного объекта. Это кажется очень громоздким, и я даже не уверен, как надежно передать большие двоичные объекты в такие EXE-файлы.

Есть ли другой подход, который я могу попробовать?

3 ответа

Решение

Вы провели довольно много исследований. Действительно, обычные веб-страницы не могут писать в файловую систему пользователя без каких-либо плагинов или расширений. Кроме того, API файловой системы HTML5 предоставляет доступ только к виртуальной файловой системе, как вы заметили.

Тем не менее, вы путаете chrome.fileSystem API с помощью HTML5 FileSystem API. В отличие от HTML FileSystem API, Chrome fileSystem (приложение) API может напрямую записывать в файловую систему пользователя (например, ~/Documents или же %USERPROFILE%\Documents), указанный пользователем.

Этот API доступен только для приложений Chrome, но не для расширений. Это не проблема, особенно если вы разрабатываете внутренний инструмент, поскольку вы можете установить приложение и расширение и использовать передачу сообщений для связи между расширением (действие страницы) и приложением (доступ к файловой системе) ( пример).


Около chrome.downloads: Поскольку ваше расширение является внутренним, вы, вероятно, можете заставить пользователей подключиться к каналу бета / разработки, чтобы использовать этот API. Единственным ограничением этого API является то, что файлы будут сохраняться в (подкаталоге) пользовательской папки загрузок.

РЕДАКТИРОВАТЬ: chrome.downloads API теперь доступен во всех каналах, включая стабильную ветку (начиная с Chrome 31).

Я боюсь, что вы сделали свою домашнюю работу, то есть вы рассмотрели все возможные альтернативы.

Лучший способ достичь именно того, чего вы хотите, - это (как вы упомянули) использовать поддерживающее нативное приложение и общаться через Native Messaging. Кстати, поскольку пропускная способность редко является проблемой в интрасетях, вам может быть проще передавать URL-адреса ресурсов (например, изображений) и загружать приложение и сохранять их.
(Да, это будет более обременительно, чем просто разработка расширения, но нужно делать то, что нужно, верно?)

С другой стороны, если вы готовы пожертвовать небольшим опытом пользователя из-за простоты разработки, я предлагаю объединить вкусности HTML5 (которые позволяют вам создавать и загружать файл локально) с библиотекой JS zipping (например, JSZip), Таким образом, пользователь должен загрузить только один zip-файл (и запрашивается только один раз). Кстати, если пользователь желает, он / она может выбрать, чтобы всегда загружать файлы без запроса (но вы уже знали это).

Используйте идею Native Messaging App.

Нативное приложение является громоздким и трудным для написания, потому что документация плохая, и если вы не получите абсолютно правильное форматирование JSON на обоих концах, вы не увидите ничего в консоли, потому что используются stdin и stdout.

Но вы будете счастливы, когда это будет сделано, потому что вы можете использовать стандартные инструменты (например, Windows Explorer, hex-редактор, TeamViewer...) для просмотра, перемещения и удаления файлов, а также для просмотра того, что происходит. Песочная файловая система Chrome работает, но теперь кажется тупиком (ни один другой браузер ее не обнаружил). Никто не может разработать сторонние инструменты для этого. Конечно, вам, вероятно, не нужны инструменты, когда все работает, но до тех пор отладка - это кошмар, потому что вам нужно писать код (и довольно много кода) только для того, чтобы отслеживать, какие файлы находятся в каких каталогах, версиях файлов, оставшихся дисковое пространство...

Другим решением для внутреннего (или может быть не внутреннего) использования является подключение к серверу websocket, локальному или удаленному.

Вы можете поместить его как в background.js, так и в content.js (используйте wss:// за https://)

var ws = new WebSocket('ws://echo.websocket.org');
// var ws = new WebSocket('ws://127.0.0.1:9000');
ws.onmessage = function(res) {
    console.log('received data:', res.data);
};
ws.onopen = function() {
    ws.send('hello');
};
Другие вопросы по тегам