хром.хранилище

Описание

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

Разрешения

storage

Обзор

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

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

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

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

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

  1. Создайте документ, находящийся вне экрана, с процедурой преобразования и обработчиком [ onMessage ][on-message].
  2. Добавьте процедуру преобразования в документ, находящийся вне поля зрения.
  3. В службе расширения проверьте наличие ваших данных chrome.storage .
  4. Если ваши данные не найдены, создайте [create][create-offscreen] документ вне экрана и вызовите [ sendMessage() ][send-message ], чтобы запустить процедуру преобразования.
  5. Внутри обработчика onMessage документа, находящегося вне экрана, вызовите процедуру преобразования.

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

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

API хранилища разделен на следующие четыре категории («области хранения»):

storage.local
Данные хранятся локально и удаляются при удалении расширения. Ограничение по квоте составляет приблизительно 10 МБ, но его можно увеличить, запросив разрешение "unlimitedStorage" . Рекомендуется использовать его для хранения больших объемов данных.
storage.sync
Если синхронизация включена, данные синхронизируются со всеми браузерами Chrome, в которые пользователь авторизован. Если отключена, работает как storage.local . Chrome сохраняет данные локально, когда браузер находится в автономном режиме, и возобновляет синхронизацию, когда он снова подключается к сети. Ограничение по квоте составляет приблизительно 100 КБ, по 8 КБ на элемент. Рекомендуется использовать эту функцию для сохранения пользовательских настроек между синхронизированными браузерами.
storage.session
Хранит данные в памяти в течение всего сеанса работы браузера. По умолчанию он не доступен для скриптов контента, но это поведение можно изменить, установив параметр chrome.storage.session.setAccessLevel() . Ограничение по квоте составляет приблизительно 10 МБ. Рекомендуется использовать его для хранения глобальных переменных между запусками сервис-воркеров.
хранилище.управляемое
Администраторы могут использовать схему и корпоративные политики для настройки параметров вспомогательного расширения в управляемой среде. Эта область хранения доступна только для чтения.

Манифест

Для использования API хранилища необходимо указать разрешение "storage" в манифесте расширения. Например:

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

Использование

Следующие примеры демонстрируют области local , sync и session хранения:

storage.local

chrome.storage.local.set({ key: value }).then(() => {
  console.log("Value is set");
});

chrome.storage.local.get(["key"]).then((result) => {
  console.log("Value currently is " + result.key);
});

storage.sync

chrome.storage.sync.set({ key: value }).then(() => {
  console.log("Value is set");
});

chrome.storage.sync.get(["key"]).then((result) => {
  console.log("Value currently is " + result.key);
});

storage.session

chrome.storage.session.set({ key: value }).then(() => {
  console.log("Value was set");
});

chrome.storage.session.get(["key"]).then((result) => {
  console.log("Value currently is " + result.key);
});

Чтобы узнать больше об managed зоне хранения, см. раздел «Манифест зон хранения» .

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

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

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

Варианты использования

В следующих разделах показаны типичные сценарии использования API хранилища.

Синхронный ответ на обновления хранилища.

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

background.js:

chrome.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;
  chrome.storage.sync.set({ options });
});

// Initialize the form with the user's option settings
const data = await chrome.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
chrome.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 = chrome.storage.sync.get().then((items) => {
  // Copy the data retrieved from storage into storageCache.
  Object.assign(storageCache, items);
});

chrome.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;
  chrome.storage.sync.set(storageCache);
});

Примеры расширений

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

Типы

AccessLevel

Chrome 102+

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

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

"НАДЕЖНЫЙ КОНТЕКСТ"
Указывает контексты, исходящие от самого расширения.

"ДОВЕРЕННЫЕ И НЕДОВЕРЕННЫЕ КОНТЕКСТЫ"
Указывает контексты, исходящие извне расширения.

StorageChange

Характеристики

  • новое значение

    любой необязательный

    Новое значение элемента, если таковое имеется.

  • старое значение

    любой необязательный

    Прежняя стоимость товара, если таковая существовала.

Характеристики

local

Предметы, находящиеся в local зоне хранения, относятся к каждой конкретной машине.

Тип

Характеристики

  • КВОТА_БАЙТЫ

    10485760

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

managed

Элементы в managed области хранения задаются корпоративной политикой, настроенной администратором домена, и доступны только для чтения для данного расширения; попытка изменить это пространство имен приведет к ошибке. Информацию о настройке политики см. в разделе «Манифест для областей хранения» .

sync

Элементы в области sync синхронизируются с помощью Chrome Sync.

Тип

Характеристики

  • MAX_ITEMS

    512

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

  • МАКСИМАЛЬНОЕ КОЛИЧЕСТВО ОПЕРАЦИЙ ЗАПИСИ В МИНУТУ

    1000000

    Устаревший

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

  • МАКСИМАЛЬНОЕ КОЛИЧЕСТВО ОПЕРАЦИЙ ЗАПИСИ В ЧАС

    1800

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

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

  • МАКСИМАЛЬНОЕ КОЛИЧЕСТВО ОПЕРАЦИЙ ЗАПИСИ В МИНУТУ

    120

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

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

  • КВОТА_БАЙТЫ

    102400

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

  • КВОТА_БАЙТОВ_НА_ТОВАР

    8192

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

События

onChanged

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

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

Параметры

  • перезвонить

    функция

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

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

    • изменения

      объект

    • areaName

      нить