browser.storage

Описание

Используйте chrome.storage API, чтобы хранить и получать пользовательские данные, а также отслеживать изменения в них.

Разрешения

storage

Чтобы использовать Storage API, объявите разрешение "storage" в манифесте расширения. Пример:

{
  "name": "My extension",
  ...
  "permissions": [
    "storage"
  ],
  ...
}

Примеры

Ниже приведены примеры хранилищ local, sync и session.

Пример (местные кампании)

await browser.storage.local.set({ key: value });
console.log("Value is set");
const result = await browser.storage.local.get(["key"]);
console.log("Value is " + result.key);

Пример (синхронизация)

await browser.storage.sync.set({ key: value });
console.log("Value is set");
const result = await browser.storage.sync.get(["key"]);
console.log("Value is " + result.key);

Пример (сеанс)

await browser.storage.session.set({ key: value });
console.log("Value is set");
const result = await browser.storage.session.get(["key"]);
console.log("Value is " + result.key);

Чтобы посмотреть другие демонстрации Storage API, изучите следующие примеры:

Основные понятия и использование

Storage API позволяет сохранять данные и состояние пользователя в расширении. Он похож на API хранилища веб-платформы (IndexedDB и Storage), но разработан с учетом потребностей расширений. Вот некоторые из основных функций:

  • Все контексты расширения, включая сервис-воркер расширения и скрипты контента, имеют доступ к Storage API.
  • Сериализуемые значения JSON хранятся как свойства объекта.
  • Storage API – это асинхронный API с операциями массового чтения и записи.
  • Даже если пользователь очистит кеш и историю браузера, данные сохранятся.
  • Сохраненные настройки не сбрасываются даже при использовании раздельного режима инкогнито.
  • Включает эксклюзивную управляемую область хранения только для чтения для корпоративных правил.

Могут ли расширения использовать API веб-хранилища?

Хотя расширения могут использовать интерфейс Storage (доступный из window.localStorage) в некоторых контекстах (всплывающие окна и другие HTML-страницы), мы не рекомендуем это делать по следующим причинам:

  • Сервисные прокси расширений не могут использовать Web Storage API.
  • Скрипты контента используют общее хранилище с хост-страницей.
  • Данные, сохраненные с помощью Web Storage API, удаляются, когда пользователь очищает историю браузера.

Чтобы перенести данные из API веб-хранилища в API хранилища расширений из сервисного работника:

  1. Подготовьте HTML-страницу и файл скрипта для документа вне экрана. Файл скрипта должен содержать процедуру преобразования и обработчик onMessage.
  2. В сервис-воркере расширения проверьте browser.storage на наличие данных.
  3. Если ваши данные не найдены, позвоните по номеру createDocument().
  4. После того как возвращенный объект Promise будет разрешен, вызовите sendMessage(), чтобы запустить процедуру конверсии.
  5. В обработчике onMessage документа вне экрана вызовите процедуру преобразования.

Также есть некоторые нюансы в работе API веб-хранилища в расширениях. Подробнее об этом рассказывается в статье Хранилище и файлы cookie.

Ограничения на хранение и регулирование

Для Storage API действуют следующие ограничения:

  • Хранение данных влияет на производительность, и API включает квоты на хранение. Планируйте, какие данные вы будете хранить, чтобы не занимать лишнее место.
  • Для завершения процесса может потребоваться некоторое время. Учитывайте это при написании кода.

Подробные сведения об ограничениях на хранение данных и о том, что происходит при их превышении, приведены в информации о квотах для sync, local и session.

Складские помещения

Storage API разделен на следующие области хранения:

Локальные

Данные хранятся локально и удаляются вместе с расширением. Объем хранилища ограничен 10 МБ (5 МБ в Chrome 113 и более ранних версиях), но его можно увеличить, запросив разрешение "unlimitedStorage". Для хранения больших объемов данных рекомендуется использовать storage.local. По умолчанию он доступен скриптам контента, но это поведение можно изменить, вызвав browser.storage.local.setAccessLevel().

Управляется

Управляемое хранилище доступно только для чтения для расширений, установленных в соответствии с правилами. Управлять ими могут системные администраторы, используя схему, заданную разработчиком, и корпоративные правила. Правила похожи на параметры, но настраиваются системным администратором, а не пользователем. Это позволяет предварительно настроить расширение для всех пользователей организации.

По умолчанию storage.managed доступен скриптам контента, но это поведение можно изменить, вызвав browser.storage.managed.setAccessLevel(). Дополнительную информацию о правилах можно найти в документации для администраторов. Подробнее managed о манифесте для областей хранения…

Сеанс

В хранилище сеансов данные хранятся в памяти, пока расширение загружено. Хранилище очищается, если расширение отключено, перезагружено или обновлено, а также при перезапуске браузера. По умолчанию он не предоставляется скриптам контента, но это поведение можно изменить, вызвав browser.storage.session.setAccessLevel(). Ограничение на объем хранилища составляет 10 МБ (1 МБ в Chrome 111 и более ранних версиях).

Интерфейс storage.session – один из нескольких, которые мы рекомендуем для сервисных работников.

Синхронизация

Если пользователь включит синхронизацию, данные будут синхронизироваться со всеми браузерами Chrome, в которых он выполнил вход. Если правило отключено, оно работает как storage.local. Если браузер не подключен к интернету, Chrome хранит данные локально и возобновляет синхронизацию при подключении к сети. Ограничение квоты составляет примерно 100 КБ, 8 КБ на элемент.

Рекомендуем использовать storage.sync, чтобы сохранять пользовательские настройки в синхронизированных браузерах. Если вы работаете с конфиденциальными пользовательскими данными, используйте storage.session. По умолчанию storage.sync доступен скриптам контента, но это поведение можно изменить, вызвав browser.storage.sync.setAccessLevel().

Методы и события

Все хранилища реализуют интерфейс StorageArea.

get()

Метод get() позволяет считывать один или несколько ключей из StorageArea.

getBytesInUse()

Метод getBytesInUse() позволяет узнать, какая часть квоты использована StorageArea.

getKeys()

Метод getKeys() позволяет получить все ключи, хранящиеся в StorageArea.

remove()

Метод remove() позволяет удалить объект из StorageArea.

set()

Метод set() позволяет задать элемент в StorageArea.

setAccessLevel()

Метод setAccessLevel() позволяет управлять доступом к StorageArea.

clear()

Метод clear() позволяет удалить все данные из StorageArea.

onChanged

Событие onChanged позволяет отслеживать изменения в StorageArea.

Примеры использования

В следующих разделах приведены примеры использования Storage API.

Реагирование на изменения в хранилище

Чтобы отслеживать изменения в хранилище, добавьте прослушиватель к его событию onChanged. Когда в хранилище что-то меняется, активируется это событие. В образце кода отслеживаются следующие изменения:

background.js:

browser.storage.onChanged.addListener((changes, namespace) => {
  for (let [key, { oldValue, newValue }] of Object.entries(changes)) {
    console.log(
      `Storage key "${key}" in namespace "${namespace}" changed.`,
      `Old value was "${oldValue}", new value is "${newValue}".`
    );
  }
});

Эту идею можно развить. В этом примере у нас есть страница настроек, которая позволяет пользователю переключать режим отладки (реализация здесь не показана). Страница параметров сразу сохраняет новые настройки в storage.sync, а сервис-воркер использует storage.onChanged, чтобы применить их как можно скорее.

options.html:

<!-- type="module" allows you to use top level await -->
<script defer src="options.js" type="module"></script>
<form id="optionsForm">
  <label for="debug">
    <input type="checkbox" name="debug" id="debug">
    Enable debug mode
  </label>
</form>

options.js:

// In-page cache of the user's options
const options = {};
const optionsForm = document.getElementById("optionsForm");

// Immediately persist options changes
optionsForm.debug.addEventListener("change", (event) => {
  options.debug = event.target.checked;
  browser.storage.sync.set({ options });
});

// Initialize the form with the user's option settings
const data = await browser.storage.sync.get("options");
Object.assign(options, data.options);
optionsForm.debug.checked = Boolean(options.debug);

background.js:

function setDebugMode() { /* ... */ }

// Watch for changes to the user's options & apply them
browser.storage.onChanged.addListener((changes, area) => {
  if (area === 'sync' && changes.options?.newValue) {
    const debugMode = Boolean(changes.options.newValue.debug);
    console.log('enable debug mode?', debugMode);
    setDebugMode(debugMode);
  }
});

Асинхронная предварительная загрузка из хранилища

Поскольку сервисные работники не работают постоянно, расширениям Manifest V3 иногда необходимо асинхронно загружать данные из хранилища перед выполнением обработчиков событий. Для этого в приведенном ниже фрагменте кода используется асинхронный обработчик событий action.onClicked, который ожидает заполнения глобальной переменной storageCache, прежде чем выполнять свою логику.

background.js:

// Where we will expose all the data we retrieve from storage.sync.
const storageCache = { count: 0 };
// Asynchronously retrieve data from storage.sync, then cache it.
const initStorageCache = browser.storage.sync.get().then((items) => {
  // Copy the data retrieved from storage into storageCache.
  Object.assign(storageCache, items);
});

browser.action.onClicked.addListener(async (tab) => {
  try {
    await initStorageCache;
  } catch (e) {
    // Handle error that occurred during storage initialization.
  }

  // Normal action handler logic.
  storageCache.count++;
  storageCache.lastTabId = tab.id;
  browser.storage.sync.set(storageCache);
});

инструменты разработчика

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

Типы

AccessLevel

Chrome 102 и более поздних версий browser.* начиная с Chrome 148

Уровень доступа к хранилищу.

Перечисление

"TRUSTED_CONTEXTS"
Указывает контексты, исходящие из самого расширения.

"TRUSTED_AND_UNTRUSTED_CONTEXTS"
Указывает контексты, которые не относятся к расширению.

StorageChange

Свойства

  • newValue

    any optional

    Новое значение объекта (если есть).

  • oldValue

    any optional

    Старое значение объекта (если оно было).

Свойства

local

Объекты в хранилище local являются локальными для каждого компьютера.

Тип

StorageArea и объект

Свойства

  • QUOTA_BYTES

    10485760

    Максимальный объем данных (в байтах), которые можно хранить в локальном хранилище. Рассчитывается как сумма длин всех ключей и значений, преобразованных в JSON-строки. Это значение будет игнорироваться, если у расширения есть разрешение unlimitedStorage. Обновления, которые приводят к превышению этого лимита, сразу же отклоняются. При этом устанавливается значение runtime.lastError (если используется обратный вызов) или отклоненный объект Promise (если используется async/await).

managed

Объекты в хранилище managed задаются корпоративным правилом, настроенным администратором домена, и доступны расширению только для чтения. Попытка изменить это пространство имен приведет к ошибке. Подробнее о том, как настроить правило…

Тип

session

Chrome 102+ browser.* начиная с Chrome 148 MV3+

Объекты в хранилище session хранятся в памяти и не сохраняются на диск.

Тип

StorageArea и объект

Свойства

  • QUOTA_BYTES

    10485760

    Максимальный объем данных (в байтах), который может храниться в памяти. Он определяется путем оценки использования динамически выделяемой памяти для каждого значения и ключа. Обновления, которые приводят к превышению этого лимита, сразу же завершаются ошибкой и устанавливают runtime.lastError при использовании обратного вызова или при отклонении Promise.

sync

Объекты в области хранения sync синхронизируются с помощью функции синхронизации Chrome.

Тип

StorageArea и объект

Свойства

  • MAX_ITEMS

    512

    Максимальное количество объектов, которые можно хранить в хранилище синхронизации. Обновления, которые приводят к превышению этого лимита, сразу же завершаются ошибкой и устанавливают runtime.lastError при использовании обратного вызова или при отклонении Promise.

  • MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE

    1 000 000

    Поддержка прекращена

    Для storage.sync API больше не используется квота на непрерывные операции записи.

  • MAX_WRITE_OPERATIONS_PER_HOUR

    1800

    Максимальное количество операций set, remove или clear, которые можно выполнить за час. Это 1 запись каждые 2 секунды, что ниже, чем краткосрочный лимит на количество записей в минуту.

    Обновления, которые приводят к превышению этого лимита, сразу же завершаются ошибкой и устанавливают runtime.lastError при использовании обратного вызова или при отклонении Promise.

  • MAX_WRITE_OPERATIONS_PER_MINUTE

    120

    Максимальное количество операций set, remove или clear, которые можно выполнить за минуту. Это 2 операции в секунду, что обеспечивает более высокую пропускную способность, чем количество операций записи в час за более короткий период времени.

    Обновления, которые приводят к превышению этого лимита, сразу же завершаются ошибкой и устанавливают runtime.lastError при использовании обратного вызова или при отклонении Promise.

  • QUOTA_BYTES

    102400

    Максимальный общий объем данных (в байтах), которые можно хранить в синхронизируемом хранилище. Рассчитывается как сумма длин всех ключей и значений, преобразованных в строки JSON. Обновления, которые приводят к превышению этого лимита, сразу же завершаются ошибкой и устанавливают runtime.lastError при использовании обратного вызова или при отклонении Promise.

  • QUOTA_BYTES_PER_ITEM

    8192

    Максимальный размер (в байтах) каждого отдельного элемента в хранилище синхронизации, определяемый как длина ключа плюс размер значения, преобразованного в строку JSON. Обновления, содержащие элементы, размер которых превышает это ограничение, будут немедленно отклонены. При этом будет установлено значение runtime.lastError (если используется обратный вызов) или отклонено обещание.

События

onChanged

browser.storage.onChanged.addListener(
  callback: function,
)

Срабатывает, когда изменяется один или несколько элементов.

Параметры

  • обратный вызов

    function

    Параметр callback выглядит следующим образом:

    (changes: object, areaName: string) => void

    • Изменения

      Объект

    • areaName

      string