Spec-Zone.ru › Web Extensions

Работа с файлами

Расширение браузера может потребоваться работать с файлами для обеспечения полной функциональности. В этой статье рассматриваются пять механизмов обработки файлов:

  • Загрузка файлов в папку загрузок пользователя.
  • Открытие файлов с помощью средства выбора файлов на веб-странице.
  • Открытие файлов с помощью перетаскивания на веб-страницу.
  • Хранение файлов или блобов локально с помощью IndexedDB с использованием библиотеки idb-file-storage.
  • Передача файлов в приложение на компьютере пользователя.

Для каждого из этих механизмов мы представим их использование с ссылками на соответствующую документацию API, руководства и примеры использования API.

Загрузка файлов с помощью API загрузки

Этот механизм позволяет загрузить файл с вашего веб-сайта (или любого расположения, которое вы можете определить как URL) на компьютер пользователя. Ключевой метод — downloads.download(), который в простейшем виде принимает URL и загружает файл с этого URL в папку загрузок по умолчанию пользователя:

browser.downloads.download({url: "https://example.org/image.png"})

Вы можете позволить пользователю загрузить файл в выбранное им расположение, указав параметр saveAs.

Примечание: Используя URL.createObjectURL(), вы также можете загрузить файлы и блоки данных, определенные в вашем JavaScript, которые могут включать локальное содержимое, полученное из IndexedDB.

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

Для использования этого API необходимо указать разрешение "downloads" API разрешения в файле manifest.json.

Пример: Последняя загрузка Справочник API: API загрузки

Открытие файлов в расширении с помощью средства выбора файла

Если вам нужно работать с файлом с компьютера пользователя, один из вариантов — позволить пользователю выбрать файл с помощью файлового обозревателя. Создайте новую страницу или внедрите код на существующую страницу для использования типа file HTML-элемента input, чтобы предложить пользователю средство выбора файла. После того, как пользователь выберет файл или файлы, скрипт, связанный со страницей, может получить доступ к содержимому файла с помощью API файлов DOM точно так же, как это делает веб-приложение.

Пример: Imagify Руководство: Использование файлов из веб-приложений Справочники API: Элемент ввода файла HTML | API файлов DOM

Примечание: Если вы хотите получить доступ к или обработать все файлы в выбранной папке, вы можете сделать это, используя <input type="file" webkitdirectory="true"/> для выбора папки и возврата всех содержащихся в ней файлов.

Открытие файлов в расширении с помощью перетаскивания

API перетаскивания веб-элементов предлагает альтернативу использованию средства выбора файла. Для использования этого метода создайте «зону выгрузки», которая соответствует вашему пользовательскому интерфейсу, затем добавьте обработчики событий dragenter, dragover и drop к элементу. В обработчике события drop ваш код может получить доступ к любому файлу, перетащенному пользователем, из объекта, предоставленного свойством dataTransfer, с помощью DataTransfer.files. Затем ваш код может получить доступ к файлам и манипулировать ими с помощью API файлов DOM.

Пример: Imagify Руководства: Использование файлов из веб-приложений | Перетаскивание файлов Справочники API: API файлов DOM

Хранение данных файлов локально с помощью библиотеки хранения файлов IndexedDB

Если вашему расширению необходимо сохранять файлы локально, библиотека idb-file-storage предоставляет простой оболочку на основе Promise к API IndexedDB для помощи в хранении и извлечении файлов и блобов.

Ключевыми особенностями библиотеки являются:

getFileStorage

Возвращает экземпляр IDBFileStorage, создавая хранилище с указанным именем, если оно не существует.

IDBFileStorage

Предоставляет методы для сохранения и извлечения файлов, такие как:

  • list для получения необязательно отфильтрованного списка файлов в базе данных.
  • put для добавления файла или блоба в базу данных.
  • get для извлечения файла или блоба из базы данных.
  • remove для удаления файла или блоба из базы данных.

Пример Хранение собранных изображений иллюстрирует, как использовать большинство этих функций.

Пример с хранением собранных изображений позволяет пользователям добавлять изображения в коллекцию с помощью пункта контекстного меню изображения. Выбранные изображения собираются в всплывающем окне и могут быть сохранены в коллекции с указанным именем. Кнопка на панели инструментов (browserAction) открывает страницу навигации по коллекции, на которой пользователь может просматривать и удалять сохраненные изображения с опцией фильтрации для сужения выбора. Посмотрите пример в действии.

Механизм работы библиотеки можно понять, посмотрев image-store.js в папке /utils/:

Создание хранилища и сохранение изображений

async function saveCollectedBlobs(collectionName, collectedBlobs) {
 const storedImages = await getFileStorage({name: "stored-images"});

 for (const item of collectedBlobs) {
    await storedImages.put(`${collectionName}/${item.uuid}`, item.blob);
 }
}

saveCollectedBlobs вызывается, когда пользователь нажимает «Сохранить» во всплывающем окне и предоставляет имя для коллекции изображений.

Сначала getFileStorage создает или извлекает базу данных IndexedDB "stored-images" в объект storedImages. storedImages.put() затем добавляет каждое собранное изображение в базу данных под именем коллекции с использованием уникального идентификатора блоба (имя файла).

Если сохраняемое изображение имеет то же имя, что и уже существующее в базе данных, оно перезаписывается. Если вы хотите этого избежать, сначала запросите базу данных с помощью imagesStore.list() с фильтром по имени файла; и, если список возвращает файл, добавьте соответствующий суффикс к имени нового изображения, чтобы сохранить отдельный элемент.

Извлечение сохраненных изображений для отображения

export async function loadStoredImages(filter) {
 const imagesStore = await getFileStorage({name: "stored-images"});
 let listOptions = filter ? {includes: filter} : undefined;
 const imagesList = await imagesStore.list(listOptions);
 let storedImages = [];
 for (const storedName of imagesList) {
    const blob = await imagesStore.get(storedName);
    storedImages.push({storedName, blobUrl: URL.createObjectURL(blob)});
 }
 return storedImages;
}

loadStoredImages() вызывается, когда пользователь нажимает «Просмотреть» или «Перезагрузить» на странице навигации по коллекции. getFileStorage() открывает базу данных "stored-images", затем imagesStore.list() получает отфильтрованный список сохраненных изображений. Этот список затем используется для извлечения изображений с помощью imagesStore.get() и создания списка для возврата в пользовательский интерфейс.

Обратите внимание на использование URL.createObjectURL(blob) для создания URL, ссылающегося на блок изображения. Этот URL затем используется в пользовательском интерфейсе (navigate-collection.jscollection.js) для отображения изображения.

END_OF_DOCUMENT_MARKER

Удаление собранных изображений

async function removeStoredImages(storedImages) {
 const imagesStore = await getFileStorage({name: "stored-images"});
 for (const storedImage of storedImages) {
    URL.revokeObjectURL(storedImage.blobUrl);
    await imagesStore.remove(storedImage.storedName);
 }
}

removeStoredImages() вызывается при нажатии пользователем кнопки «Удалить» на странице навигации по коллекции. Опять же, getFileStorage() открывает базу данных "stored-images", а затем imagesStore.remove() удаляет каждое изображение из отфильтрованного списка изображений.

Обратите внимание на использование URL.revokeObjectURL() для явного отзыва URL объекта blob. Это позволяет сборщику мусора освободить память, выделенную для URL. Если этого не сделать, память не будет возвращена до тех пор, пока страница, на которой она была создана, не будет закрыта. Если URL был создан на странице расширения (фоновая страница), он не разгружается до тех пор, пока расширение не будет отключено, удалено или перезагружено, поэтому излишнее удержание этой памяти может повлиять на производительность браузера. Если URL создается на странице расширения (новая вкладка, всплывающее окно или боковая панель), память освобождается при закрытии страницы, но все равно рекомендуется отзывать URL, когда он больше не нужен.

После отзыва URL объекта blob любая попытка загрузить его приведет к ошибке. Например, если URL объекта blob использовался в качестве атрибута SRC тега IMG, изображение не загрузится и не отобразится. Поэтому рекомендуется удалять любые отозванные URL объекта blob из сгенерированных HTML-элементов при отзыве URL объекта blob.

Пример: Хранение собранных изображений Справочные материалы по API: библиотека idb-file-storage

Примечание: Вы также можете использовать весь веб-API IndexedDB API для хранения данных из расширения. Это может быть полезно, когда вам нужно хранить данные, которые плохо обрабатываются простыми парами ключ/значение, предлагаемыми API хранилища DOM Storage API.

Обработка файлов в локальном приложении

В случае наличия собственного приложения или необходимости предоставления дополнительных функций обработки файлов для обработки файлов используйте родной механизм обмена сообщениями для передачи файла в родное приложение для обработки.

У вас есть два варианта:

Связанное обменом сообщениями

Здесь вы запускаете процесс с runtime.connectNative(), который возвращает объект runtime.Port. Затем вы можете передать JSON-сообщение в родное приложение, используя функцию postMessage() объекта Port. С помощью функции onMessage.addListener() объекта Port можно прослушивать сообщения от родного приложения. Родное приложение открывается, если оно не запущено при вызове runtime.connectNative(), и приложение остается запущенным до тех пор, пока расширение не вызовет Port.disconnect() или страница, которая с ним соединена, не будет закрыта.

Обмен сообщениями без подключения

Здесь вы используете runtime.sendNativeMessage() для отправки JSON-сообщения в новую временную инстанцию родного приложения. После получения любого сообщения обратно от родного приложения браузер закрывает родное приложение.

Чтобы добавить файл или blob, который вы хотите обработать в родном приложении, используйте JSON.stringify().

Для использования этого метода расширение должно запросить разрешение "nativeMessaging" разрешение или дополнительное разрешение в своем файле manifest.json. При использовании дополнительного разрешения не забудьте проверить, предоставлено ли это разрешение, и при необходимости запросить разрешение у пользователя с помощью API permissions. Взаимно родное приложение должно предоставить разрешение расширению, включив его идентификатор в поле "allowed_extensions" файла манифеста приложения.

Пример: Родные сообщения (иллюстрирует только простой обмен сообщениями) Руководства: Родные сообщения Справочные материалы по API: API runtime

© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Working_with_files

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API