Описание
Используйте API chrome.storage для хранения, извлечения и отслеживания изменений пользовательских данных.
Разрешения
storageОбзор
API хранилища предоставляет специфичный для расширений способ сохранения пользовательских данных и состояния. Он похож на API хранилища веб-платформы ( IndexedDB и Storage ), но был разработан для удовлетворения потребностей расширений в хранении данных. Ниже приведены некоторые ключевые особенности:
- Все контексты расширений, включая обработчик службы расширений и скрипты контента, имеют доступ к API хранилища.
- Значения, сериализуемые в формате JSON, хранятся в виде свойств объекта.
- API хранилища работает асинхронно и поддерживает пакетные операции чтения и записи.
- Даже если пользователь очистит кэш и историю просмотров, данные сохранятся.
- Сохраненные настройки сохраняются даже при использовании режима разделенного экрана инкогнито .
- Включает в себя эксклюзивную управляемую область хранения только для чтения для корпоративных политик.
Хотя расширения могут использовать интерфейс [ Storage ][mdn-storage] (доступный через window.localStorage ) в некоторых контекстах (всплывающие окна и другие HTML-страницы), это не рекомендуется по следующим причинам:
- Сервисный работник расширения не может получить доступ
Storage. - Скрипты контента используют общее хранилище с основной страницей.
- Сохраненные через интерфейс
Storageданные теряются при очистке пользователем истории просмотров.
Для переноса данных из API веб-хранилища в API расширенного хранилища из сервис-воркера:
- Создайте документ, находящийся вне экрана, с процедурой преобразования и обработчиком [
onMessage][on-message]. - Добавьте процедуру преобразования в документ, находящийся вне поля зрения.
- В службе расширения проверьте наличие ваших данных
chrome.storage. - Если ваши данные не найдены, создайте [create][create-offscreen] документ вне экрана и вызовите [
sendMessage()][send-message ], чтобы запустить процедуру преобразования. - Внутри обработчика
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
Уровень доступа к складскому помещению.
Перечисление
"НАДЕЖНЫЙ КОНТЕКСТ" "ДОВЕРЕННЫЕ И НЕДОВЕРЕННЫЕ КОНТЕКСТЫ"
Указывает контексты, исходящие от самого расширения.
Указывает контексты, исходящие извне расширения.
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
нить