Opis
Użyj interfejsu chrome.storage API, aby przechowywać, pobierać i śledzić zmiany danych użytkownika.
Uprawnienia
storageAby używać interfejsu Storage API, zadeklaruj uprawnienie "storage" w pliku manifestu rozszerzenia
. Na przykład:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
Przykłady
Poniższe przykłady pokazują obszary pamięci local, sync i session:
Przykład (lokalny)
await chrome.storage.local.set({ key: value });
console.log("Value is set");
const result = await chrome.storage.local.get(["key"]);
console.log("Value is " + result.key);
Przykład (synchronizacja)
await chrome.storage.sync.set({ key: value });
console.log("Value is set");
const result = await chrome.storage.sync.get(["key"]);
console.log("Value is " + result.key);
Przykład (sesja)
await chrome.storage.session.set({ key: value });
console.log("Value is set");
const result = await chrome.storage.session.get(["key"]);
console.log("Value is " + result.key);
Aby zobaczyć inne prezentacje interfejsu Storage API, zapoznaj się z tymi przykładami:
Pojęcia i użycie
Interfejs Storage API zapewnia sposób utrwalania danych i stanu użytkownika specyficzny dla rozszerzenia. Jest podobny do interfejsów Storage API platformy internetowej (IndexedDB i Storage), ale został zaprojektowany tak, aby spełniać potrzeby rozszerzeń w zakresie przechowywania danych. Oto kilka najważniejszych funkcji:
- Wszystkie konteksty rozszerzeń, w tym skrypty treści i skrypt service worker rozszerzenia, mają dostęp do interfejsu Storage API.
- Wartości serializowane w formacie JSON są przechowywane jako właściwości obiektu.
- Interfejs Storage API jest asynchroniczny i obsługuje operacje odczytu i zapisu zbiorczego.
- Dane są zachowywane nawet wtedy, gdy użytkownik wyczyści pamięć podręczną i historię przeglądania.
- Zapisane ustawienia są zachowywane nawet w przypadku korzystania z trybu incognito.
- Zawiera wyłączny obszar pamięci zarządzanej tylko do odczytu na potrzeby zasad firmy.
Czy rozszerzenia mogą używać interfejsów Web Storage API?
Chociaż rozszerzenia mogą używać interfejsu Storage (dostępnego z window.localStorage) w niektórych kontekstach (wyskakujące okienko i inne strony HTML), nie zalecamy tego z tych powodów:
- Service worker rozszerzenia nie mogą używać interfejsu Web Storage API.
- Skrypty treści współdzielą pamięć ze stroną hostującą.
- Dane zapisane za pomocą interfejsu Web Storage API są tracone, gdy użytkownik wyczyści historię przeglądania.
Aby przenieść dane z interfejsów Web Storage API do interfejsów Extension Storage API ze skryptu service worker:
- Przygotuj stronę HTML dokumentu poza ekranem i plik skryptu. Plik skryptu powinien zawierać procedurę konwersji i obsługę
onMessage. - W skrypcie service worker rozszerzenia sprawdź, czy dane znajdują się w
chrome.storage. - Jeśli nie znajdziesz danych, wywołaj
createDocument(). - Gdy zwrócona obietnica zostanie rozwiązana, wywołaj
sendMessage(), aby rozpocząć procedurę konwersji. - W obsłudze
onMessagedokumentu poza ekranem wywołaj procedurę konwersji.
Istnieją też pewne niuanse dotyczące działania interfejsów Web Storage API w rozszerzeniach. Więcej informacji znajdziesz w artykule Miejsce na dane i pliki cookie.
Miejsce na dane i limity ograniczania
Interfejs Storage API ma ograniczenia dotyczące użycia:
- Przechowywanie danych wiąże się z kosztami wydajności, a interfejs API obejmuje limity miejsca na dane. Zaplanuj dane, które chcesz przechowywać, aby zachować miejsce na dane.
- Przechowywanie danych może zająć trochę czasu. Zaprojektuj kod tak, aby uwzględniał ten czas.
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.
Obszary pamięci
Interfejs Storage API jest podzielony na te obszary pamięci:
Lokalne
Dane są przechowywane lokalnie i usuwane po usunięciu rozszerzenia. Limit miejsca na dane wynosi 10 MB (5 MB w Chrome 113 i starszych wersjach), ale można go zwiększyć, prosząc o uprawnienie "unlimitedStorage". Do przechowywania większych ilości danych zalecamy używanie storage.local. Domyślnie jest on udostępniany skryptom treści, ale można to zmienić, wywołując chrome.storage.local.setAccessLevel().
Zarządzane
Miejsce na dane zarządzane jest tylko do odczytu w przypadku rozszerzeń zainstalowanych przez zasady. Zarządzają nim administratorzy systemu za pomocą zdefiniowanego przez dewelopera schematu i zasad firmy. Zasady są podobne do opcji, ale są konfigurowane przez administratora systemu, a nie przez użytkownika. Dzięki temu rozszerzenie można wstępnie skonfigurować dla wszystkich użytkowników organizacji.
Domyślnie storage.managed jest udostępniany skryptom treści, ale można to zmienić, wywołując chrome.storage.managed.setAccessLevel(). Więcej informacji o zasadach znajdziesz w dokumentacji dla administratorów. Więcej informacji o obszarze pamięci managed znajdziesz w manifeście obszarów pamięci.
Sesja
Miejsce na dane sesji przechowuje dane w pamięci, gdy rozszerzenie jest wczytane. Miejsce na dane jest czyszczone, gdy rozszerzenie jest wyłączone, ponownie wczytane, zaktualizowane lub gdy przeglądarka zostanie ponownie uruchomiona. Domyślnie nie jest on udostępniany skryptom treści, ale można to zmienić, wywołując chrome.storage.session.setAccessLevel(). Limit miejsca na dane wynosi 10 MB (1 MB w Chrome 111 i starszych wersjach).
Interfejs storage.session jest jednym z kilku które zalecamy w przypadku service worker.
Synchronizacja
Jeśli użytkownik włączy synchronizację, dane będą 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 przechowuje dane lokalnie i wznawia synchronizację, gdy przeglądarka jest ponownie online. Limit wynosi około 100 KB, czyli 8 KB na element.
Zalecamy używanie storage.sync, aby zachować ustawienia użytkownika w synchronizowanych przeglądarkach. Jeśli pracujesz z poufnymi danymi użytkownika, użyj storage.session. Domyślnie storage.sync jest udostępniany skryptom treści, ale można to zmienić, wywołując chrome.storage.sync.setAccessLevel().
Metody i zdarzenia
Wszystkie obszary pamięci implementują interfejs StorageArea.
get()
Metoda get() umożliwia odczytanie co najmniej 1 klucza z StorageArea.
getBytesInUse()
Metoda getBytesInUse() umożliwia sprawdzenie limitu używanego przez StorageArea.
getKeys()
Metoda getKeys() umożliwia pobranie wszystkich kluczy przechowywanych w StorageArea.
remove()
Metoda remove() umożliwia usunięcie elementu z StorageArea.
set()
Metoda set() umożliwia ustawienie elementu w StorageArea.
setAccessLevel()
Metoda setAccessLevel() umożliwia kontrolowanie dostępu do StorageArea.
clear()
Metoda clear() umożliwia wyczyszczenie wszystkich danych z StorageArea.
onChanged
Zdarzenie onChanged umożliwia monitorowanie zmian w StorageArea.
Przypadki użycia
W sekcjach poniżej znajdziesz typowe przypadki użycia interfejsu Storage API.
Reagowanie na aktualizacje miejsca na dane
Aby śledzić zmiany wprowadzone w miejscu na dane, dodaj detektor do zdarzenia onChanged. Gdy coś się zmieni w miejscu na dane, 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 rozwinąć ten pomysł. W tym przykładzie mamy stronę opcji, która
umożliwia użytkownikowi włączanie i wyłączanie „trybu debugowania” (implementacja nie jest tu pokazana). Strona opcji natychmiast zapisuje nowe ustawienia w storage.sync, a skrypt 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 wczytywanie wstępne z miejsca na dane
Ponieważ service worker nie działają cały czas, rozszerzenia Manifest V3 czasami muszą asynchronicznie wczytywać dane z miejsca na dane, zanim wykonają swoje obsługi zdarzeń. Aby to zrobić, poniższy fragment kodu używa asynchronicznego modułu obsługi zdarzeń action.onClicked, który czeka na wypełnienie globalnej zmiennej 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);
});
DevTools
Dane przechowywane za pomocą interfejsu API możesz wyświetlać i edytować w Narzędziach deweloperskich. Więcej informacji znajdziesz na stronie Wyświetlanie i edytowanie miejsca na dane rozszerzenia w dokumentacji Narzędzi deweloperskich.
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.
StorageChange
Właściwości
-
newValue
any optional
Nowa wartość elementu, jeśli istnieje.
-
oldValue
any optional
Stara wartość elementu, jeśli istniała.
Właściwości
local
Elementy w obszarze pamięci local są lokalne dla każdego komputera.
Typ
StorageArea & object
Właściwości
-
QUOTA_BYTES
10485760
Maksymalna ilość danych (w bajtach), które można przechowywać w pamięci lokalnej, mierzona przez serializację JSON każdej wartości oraz długość 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ąruntime.lastError, jeśli używasz wywołania zwrotnego, lub odrzuconą obietnicę, jeśli używasz 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 spowoduje błąd. Więcej informacji o konfigurowaniu zasad znajdziesz w manifeście obszarów pamięci.
Typ
session
Elementy w obszarze pamięci session są przechowywane w pamięci i nie będą utrwalane na dysku.
Typ
StorageArea & object
Właściwości
-
QUOTA_BYTES
10485760
Maksymalna ilość danych (w bajtach), które można przechowywać w pamięci, mierzona przez oszacowanie dynamicznie przydzielonego wykorzystania pamięci każdej wartości i klucza. Aktualizacje, które spowodowałyby przekroczenie tego limitu, natychmiast się nie powiodą i ustawią
runtime.lastError, jeśli używasz wywołania zwrotnego, lub gdy obietnica zostanie odrzucona.
sync
Elementy w obszarze pamięci sync są synchronizowane za pomocą Synchronizacji Chrome.
Typ
StorageArea & object
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ą
runtime.lastError, jeśli używasz wywołania zwrotnego, lub gdy obietnica zostanie odrzucona. -
MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE
1000000
WycofanoInterfejs storage.sync API nie ma już limitu operacji zapisu.
-
MAX_WRITE_OPERATIONS_PER_HOUR
1800
Maksymalna liczba operacji
set,removelubclear, które można wykonać w ciągu godziny. Wynosi ona 1 co 2 sekundy, czyli mniej 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ą
runtime.lastError, jeśli używasz wywołania zwrotnego, lub gdy obietnica zostanie odrzucona. -
MAX_WRITE_OPERATIONS_PER_MINUTE
120
Maksymalna liczba operacji
set,removelubclear, które można wykonać w ciągu minuty. Wynosi ona 2 na sekundę, co zapewnia większą przepustowość niż zapisy na godzinę w krótszym okresie.Aktualizacje, które spowodowałyby przekroczenie tego limitu, natychmiast się nie powiodą i ustawią
runtime.lastError, jeśli używasz wywołania zwrotnego, lub gdy obietnica zostanie odrzucona. -
QUOTA_BYTES
102400
Maksymalna łączna ilość danych (w bajtach), które można przechowywać w pamięci synchronizacji, mierzona przez serializację JSON każdej wartości oraz długość każdego klucza. Aktualizacje, które spowodowałyby przekroczenie tego limitu, natychmiast się nie powiodą i ustawią
runtime.lastError, jeśli używasz wywołania zwrotnego, lub gdy obietnica zostanie odrzucona. -
QUOTA_BYTES_PER_ITEM
8192
Maksymalny rozmiar (w bajtach) każdego elementu w pamięci synchronizacji, mierzony przez serializację JSON jego wartości oraz długość klucza. Aktualizacje zawierające elementy większe niż ten limit natychmiast się nie powiodą i ustawią
runtime.lastError, jeśli używasz wywołania zwrotnego, lub gdy obietnica zostanie odrzucona.
Wydarzenia
onChanged
chrome.storage.onChanged.addListener(
callback: function,
)
Wywoływane, gdy zmieni się co najmniej 1 element.
Parametry
-
callback
function
Parametr
callbackwygląda tak:(changes: object, areaName: string) => void
-
changes
object
-
areaName
string
-