Описание
Используйте 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 хранилища расширений из сервисного работника:
- Подготовьте HTML-страницу и файл скрипта для документа вне экрана. Файл скрипта должен содержать процедуру преобразования и обработчик
onMessage. - В сервис-воркере расширения проверьте
browser.storageна наличие данных. - Если ваши данные не найдены, позвоните по номеру
createDocument(). - После того как возвращенный объект Promise будет разрешен, вызовите
sendMessage(), чтобы запустить процедуру конверсии. - В обработчике
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
Уровень доступа к хранилищу.
Перечисление
"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
Объекты в хранилище 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
-