Opis
Używaj interfejsu chrome.storage
API do przechowywania, pobierania i śledzenia zmian w danych użytkowników.
Uprawnienia
storage
Przegląd
Interfejs Storage API zapewnia sposób na utrwalanie danych i stanu użytkownika, który jest specyficzny dla rozszerzenia. Jest podobny do interfejsów API pamięci masowej platformy internetowej (IndexedDB i Storage), ale został zaprojektowany z myślą o potrzebach rozszerzeń w zakresie przechowywania danych. Oto kilka najważniejszych funkcji:
- Wszystkie konteksty rozszerzenia, w tym skrypt usługi rozszerzenia i skrypty treści, mają dostęp do interfejsu Storage API.
- Wartości, które można serializować do formatu JSON, są przechowywane jako właściwości obiektu.
- Interfejs Storage API jest asynchroniczny i umożliwia zbiorcze operacje odczytu i zapisu.
- Nawet jeśli użytkownik wyczyści pamięć podręczną i historię przeglądania, dane pozostaną.
- Zapisane ustawienia są zachowywane nawet podczas korzystania z podzielonego trybu incognito.
- Obejmuje ekskluzywny obszar zarządzanej pamięci tylko do odczytu na potrzeby zasad przedsiębiorstwa.
Mimo że rozszerzenia mogą w niektórych kontekstach (wyskakujące okienko i inne strony HTML) korzystać z interfejsu [Storage
][mdn-storage] (dostępnego z window.localStorage
), nie jest to zalecane z tych powodów:
- Element service worker rozszerzenia nie ma dostępu do adresu
Storage
. - Skrypty treści współdzielą pamięć masową ze stroną hostującą.
- Dane zapisane za pomocą interfejsu
Storage
zostaną utracone, gdy użytkownik wyczyści historię przeglądania.
Aby przenieść dane z interfejsów API pamięci internetowej do interfejsów API pamięci rozszerzeń z poziomu skryptu service worker:
- Utwórz dokument poza ekranem z procedurą konwersji i procedurą obsługi [
onMessage
][on-message]. - Dodaj procedurę konwersji do dokumentu poza ekranem.
- W usłudze service worker rozszerzenia sprawdź
chrome.storage
swoje dane. - Jeśli dane nie zostaną znalezione, [utwórz][create-offscreen] dokument poza ekranem i wywołaj [
sendMessage()
][send-message], aby rozpocząć procedurę konwersji. - W obsłudze
onMessage
dokumentu poza ekranem wywołaj procedurę konwersji.
Istnieją też pewne niuanse dotyczące działania interfejsów API pamięci internetowej w rozszerzeniach. Więcej informacji znajdziesz w artykule [Miejsce na dane i pliki cookie][storage-and-cookies].
Miejsca do przechowywania
Interfejs Storage API jest podzielony na 4 obszary pamięci:
storage.local
- Dane są przechowywane lokalnie i usuwane po usunięciu rozszerzenia. Limit przydziału wynosi około 10 MB, ale można go zwiększyć, prosząc o uprawnienie
"unlimitedStorage"
. Możesz go używać do przechowywania większych ilości danych.
storage.sync
- Jeśli synchronizacja jest włączona, dane są synchronizowane z każdą przeglądarką Chrome, w której użytkownik jest zalogowany. Jeśli jest wyłączona, działa jak
storage.local
. Gdy przeglądarka jest offline, Chrome zapisuje dane lokalnie i wznawia synchronizację po ponownym połączeniu z internetem. Limit wynosi około 100 KB, czyli 8 KB na element. Możesz go użyć, aby zachować ustawienia użytkownika na wszystkich zsynchronizowanych przeglądarkach.
- storage.session
- Przechowuje dane w pamięci przez czas trwania sesji przeglądarki. Domyślnie nie jest on udostępniany skryptom treści, ale można to zmienić, ustawiając wartość
chrome.storage.session.setAccessLevel()
. Limit wynosi około 10 MB. Możesz go używać do przechowywania zmiennych globalnych w różnych uruchomieniach skryptu service worker.
- storage.managed
- Administratorzy mogą używać schematu i zasad przedsiębiorstwa do konfigurowania ustawień rozszerzenia pomocniczego w środowisku zarządzanym. Ten obszar pamięci jest tylko do odczytu.
Plik manifestu
Aby korzystać z interfejsu Storage API, zadeklaruj uprawnienie "storage"
w pliku manifestu rozszerzenia. Na przykład:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
Wykorzystanie
Poniższe przykłady pokazują obszary pamięci local
, sync
i 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);
});
Więcej informacji o obszarze pamięci managed
znajdziesz w manifestach obszarów pamięci.
Limity miejsca na dane i ograniczenia przepustowości
Nie myśl o dodawaniu danych do interfejsu Storage API jak o umieszczaniu rzeczy w dużej ciężarówce. Dodawanie danych do pamięci przypomina wkładanie czegoś do rury. Rura może już zawierać materiał, a nawet być wypełniona. Zawsze zakładaj opóźnienie między dodaniem informacji do pamięci a ich faktycznym zapisaniem.
Szczegółowe informacje o ograniczeniach obszaru pamięci i o tym, co się dzieje po ich przekroczeniu, znajdziesz w informacjach o limitach dla sync
, local
i session
.
Przypadki użycia
W sekcjach poniżej znajdziesz typowe przypadki użycia interfejsu Storage API.
Synchroniczna odpowiedź na aktualizacje miejsca na dane
Aby śledzić zmiany wprowadzone w pamięci, możesz dodać detektor do zdarzenia onChanged
. Gdy w pamięci zmieni się cokolwiek, to zdarzenie zostanie wywołane. Przykładowy kod nasłuchuje tych zmian:
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}".`
);
}
});
Możemy pójść o krok dalej. W tym przykładzie mamy stronę opcji, która umożliwia użytkownikowi włączenie i wyłączenie „trybu debugowania” (implementacja nie jest tu pokazana). Strona opcji natychmiast zapisuje nowe ustawienia w storage.sync
, a service worker używa storage.onChanged
, aby jak najszybciej zastosować ustawienie.
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);
}
});
Asynchroniczne wstępne wczytywanie z pamięci
Ponieważ procesy service worker nie zawsze działają, rozszerzenia w wersji Manifest V3 czasami muszą asynchronicznie wczytywać dane z pamięci, zanim wykonają swoje procedury obsługi zdarzeń. W tym celu poniższy fragment kodu używa asynchronicznego modułu obsługi zdarzeń action.onClicked
, który czeka na wypełnienie obiektu globalnego storageCache
, zanim wykona swoją logikę.
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);
});
Przykłady rozszerzeń
Aby zobaczyć inne wersje demonstracyjne interfejsu Storage API, zapoznaj się z tymi przykładami:
Typy
AccessLevel
Poziom dostępu do obszaru pamięci.
Typ wyliczeniowy
„TRUSTED_CONTEXTS”
Określa konteksty pochodzące z samego rozszerzenia.
"TRUSTED_AND_UNTRUSTED_CONTEXTS"
Określa konteksty pochodzące spoza rozszerzenia.
StorageArea
Właściwości
-
onChanged
Event<functionvoidvoid>
Chrome 73 lub nowszaWywoływane, gdy zmieni się co najmniej 1 element.
Funkcja
onChanged.addListener
wygląda tak:(callback: function) => {...}
-
callback
funkcja
Parametr
callback
wygląda tak:(changes: object) => void
-
Zmiany
obiekt
-
-
-
wyczyść
pusty,
ObietnicaUsuwa wszystkie elementy z pamięci.
Funkcja
clear
wygląda tak:(callback?: function) => {...}
-
callback
funkcja opcjonalna
Parametr
callback
wygląda tak:() => void
-
returns
Promise<void>
Chrome 95 lub nowszyObietnice są obsługiwane tylko w przypadku platformy Manifest V3 i nowszych. Inne platformy muszą używać wywołań zwrotnych.
-
-
get
pusty,
ObietnicaPobiera co najmniej 1 element z pamięci.
Funkcja
get
wygląda tak:(keys?: string | string[] | object, callback?: function) => {...}
-
klucze
string | string[] | object opcjonalny
Pojedynczy klucz do pobrania, lista kluczy do pobrania lub słownik określający wartości domyślne (patrz opis obiektu). Pusta lista lub pusty obiekt zwrócą pusty obiekt wyniku. Przekaż
null
, aby uzyskać całą zawartość pamięci. -
callback
funkcja opcjonalna
Parametr
callback
wygląda tak:(items: object) => void
-
items
obiekt
Obiekt z elementami w mapowaniach par klucz-wartość.
-
-
returns
Promise<object>
Chrome 95 lub nowszyObietnice są obsługiwane tylko w przypadku platformy Manifest V3 i nowszych. Inne platformy muszą używać wywołań zwrotnych.
-
-
getBytesInUse
pusty,
ObietnicaPobiera ilość miejsca (w bajtach) zajmowanego przez co najmniej 1 element.
Funkcja
getBytesInUse
wygląda tak:(keys?: string | string[], callback?: function) => {...}
-
klucze
string | string[] opcjonalny
Pojedynczy klucz lub lista kluczy, dla których chcesz uzyskać łączne wykorzystanie. Pusta lista zwróci wartość 0. Przekaż wartość
null
, aby uzyskać łączne wykorzystanie wszystkich miejsc na dane. -
callback
funkcja opcjonalna
Parametr
callback
wygląda tak:(bytesInUse: number) => void
-
bytesInUse
liczba
Ilość wykorzystywanego miejsca na dane (w bajtach).
-
-
returns
Promise<number>
Chrome 95 lub nowszyObietnice są obsługiwane tylko w przypadku platformy Manifest V3 i nowszych. Inne platformy muszą używać wywołań zwrotnych.
-
-
getKeys
pusty,
Promise Chrome 130+Pobiera wszystkie klucze z pamięci.
Funkcja
getKeys
wygląda tak:(callback?: function) => {...}
-
callback
funkcja opcjonalna
Parametr
callback
wygląda tak:(keys: string[]) => void
-
klucze
string[]
Tablica z kluczami odczytanymi z pamięci.
-
-
returns
Promise<string[]>
Obietnice są obsługiwane tylko w przypadku platformy Manifest V3 i nowszych. Inne platformy muszą używać wywołań zwrotnych.
-
-
usuń
pusty,
ObietnicaUsuwa co najmniej 1 element z pamięci.
Funkcja
remove
wygląda tak:(keys: string | string[], callback?: function) => {...}
-
klucze
string | string[]
Pojedynczy klucz lub lista kluczy elementów do usunięcia.
-
callback
funkcja opcjonalna
Parametr
callback
wygląda tak:() => void
-
returns
Promise<void>
Chrome 95 lub nowszyObietnice są obsługiwane tylko w przypadku platformy Manifest V3 i nowszych. Inne platformy muszą używać wywołań zwrotnych.
-
-
zestaw
pusty,
ObietnicaUstawia wiele elementów.
Funkcja
set
wygląda tak:(items: object, callback?: function) => {...}
-
items
obiekt
Obiekt, który zawiera pary klucz-wartość do aktualizacji pamięci. Nie wpłynie to na inne pary klucz/wartość w pamięci.
Wartości pierwotne, takie jak liczby, będą serializowane zgodnie z oczekiwaniami. Wartości ze znakami
typeof
,"object"
i"function"
są zwykle serializowane jako{}
, z wyjątkiem znakówArray
(serializowany zgodnie z oczekiwaniami),Date
iRegex
(serializowane przy użyciu reprezentacjiString
). -
callback
funkcja opcjonalna
Parametr
callback
wygląda tak:() => void
-
returns
Promise<void>
Chrome 95 lub nowszyObietnice są obsługiwane tylko w przypadku platformy Manifest V3 i nowszych. Inne platformy muszą używać wywołań zwrotnych.
-
-
setAccessLevel
pusty,
Promise Chrome 102 lub nowszyUstawia żądany poziom dostępu do obszaru pamięci. Domyślnie pamięć
session
jest ograniczona do zaufanych kontekstów (stron rozszerzeń i skryptów service worker), a pamięćlocal
isync
umożliwia dostęp zarówno z zaufanych, jak i niezaufanych kontekstów.Funkcja
setAccessLevel
wygląda tak:(accessOptions: object, callback?: function) => {...}
-
accessOptions
obiekt
-
accessLevel
Poziom dostępu do obszaru pamięci.
-
-
callback
funkcja opcjonalna
Parametr
callback
wygląda tak:() => void
-
returns
Promise<void>
Obietnice są obsługiwane tylko w przypadku platformy Manifest V3 i nowszych. Inne platformy muszą używać wywołań zwrotnych.
-
StorageChange
Właściwości
-
newValue
dowolny opcjonalny
Nowa wartość produktu, jeśli taka istnieje.
-
oldValue
dowolny opcjonalny
Stara wartość produktu, jeśli taka istniała.
Właściwości
local
Elementy w obszarze pamięci local
są lokalne dla każdego urządzenia.
Typ
StorageArea i obiekt
Właściwości
-
QUOTA_BYTES
10485760
Maksymalna ilość danych (w bajtach), które można przechowywać w pamięci lokalnej, mierzona za pomocą serializacji JSON każdej wartości oraz długości każdego klucza. Ta wartość zostanie zignorowana, jeśli rozszerzenie ma uprawnienie
unlimitedStorage
. Aktualizacje, które spowodowałyby przekroczenie tego limitu, natychmiast się nie powiodą i ustawią wartośćruntime.lastError
, jeśli używasz wywołania zwrotnego, lub odrzuconą obietnicę, jeśli używasz funkcji async/await.
managed
Elementy w obszarze pamięci managed
są ustawiane przez zasady firmy skonfigurowane przez administratora domeny i są tylko do odczytu dla rozszerzenia. Próba zmodyfikowania tej przestrzeni nazw powoduje błąd. Informacje o konfigurowaniu zasad znajdziesz w artykule Manifest obszarów pamięci.
Typ
sync
Elementy w obszarze pamięci sync
są synchronizowane za pomocą Synchronizacji Chrome.
Typ
StorageArea i obiekt
Właściwości
-
MAX_ITEMS
512
Maksymalna liczba elementów, które można przechowywać w pamięci synchronizacji. Aktualizacje, które spowodowałyby przekroczenie tego limitu, natychmiast się nie powiodą i ustawią wartość
runtime.lastError
, gdy używane jest wywołanie zwrotne lub gdy obietnica zostanie odrzucona. -
MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE
1000000
WycofanoInterfejs storage.sync API nie ma już limitu trwałej operacji zapisu.
-
MAX_WRITE_OPERATIONS_PER_HOUR
1800
Maksymalna liczba operacji
set
,remove
lubclear
, które można wykonać w ciągu godziny. Jest to 1 co 2 sekundy, czyli niższy limit niż krótkoterminowy limit większej liczby zapisów na minutę.Aktualizacje, które spowodowałyby przekroczenie tego limitu, natychmiast się nie powiodą i ustawią wartość
runtime.lastError
, gdy używane jest wywołanie zwrotne lub gdy obietnica zostanie odrzucona. -
MAX_WRITE_OPERATIONS_PER_MINUTE
120
Maksymalna liczba operacji
set
,remove
lubclear
, które można wykonać w ciągu minuty. Wynosi ona 2 operacje na sekundę, co zapewnia większą przepustowość niż operacje zapisu na godzinę w krótszym okresie.Aktualizacje, które spowodowałyby przekroczenie tego limitu, natychmiast się nie powiodą i ustawią wartość
runtime.lastError
, gdy używane jest wywołanie zwrotne lub gdy obietnica zostanie odrzucona. -
QUOTA_BYTES
102400
Maksymalna łączna ilość danych (w bajtach), które można przechowywać w pamięci synchronizacji. Jest ona mierzona na podstawie serializacji JSON każdej wartości oraz długości każdego klucza. Aktualizacje, które spowodowałyby przekroczenie tego limitu, natychmiast się nie powiodą i ustawią wartość
runtime.lastError
, gdy używane jest wywołanie zwrotne lub gdy obietnica zostanie odrzucona. -
QUOTA_BYTES_PER_ITEM
8192
Maksymalny rozmiar (w bajtach) każdego elementu w pamięci synchronizacji, mierzony jako ciąg znaków JSON jego wartości plus długość klucza. Aktualizacje zawierające elementy większe niż ten limit natychmiast się nie powiodą i ustawią
runtime.lastError
, gdy używane jest wywołanie zwrotne lub gdy obietnica zostanie odrzucona.
Wydarzenia
onChanged
chrome.storage.onChanged.addListener(
callback: function,
)
Wywoływane, gdy zmieni się co najmniej 1 element.
Parametry
-
callback
funkcja
Parametr
callback
wygląda tak:(changes: object, areaName: string) => void
-
Zmiany
obiekt
-
areaName
ciąg znaków
-