תיאור
משתמשים ב-chrome.storage
API כדי לאחסן נתוני משתמשים, לאחזר אותם ולעקוב אחרי שינויים בהם.
הרשאות
storage
כדי להשתמש ב-Storage API, צריך להצהיר על ההרשאה "storage"
במניפסט של התוסף. לדוגמה:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
מושגים ושימוש
Storage API מספק דרך ספציפית לתוסף לשמור נתוני משתמשים ומצב. הוא דומה לממשקי ה-API של האחסון בפלטפורמת האינטרנט (IndexedDB ו-Storage), אבל הוא תוכנן כדי לענות על צורכי האחסון של התוספים. אלה כמה מהתכונות העיקריות:
- לכל ההקשרים של התוסף, כולל ה-service worker והסקריפטים של התוכן של התוסף, יש גישה ל-Storage API.
- הערכים שניתנים לסריאליזציה ב-JSON מאוחסנים כמאפייני אובייקט.
- Storage API הוא אסינכרוני עם פעולות קריאה וכתיבה בכמות גדולה.
- הנתונים נשמרים גם אם המשתמש מנקה את המטמון ואת היסטוריית הגלישה.
- ההגדרות שנשמרו נשארות גם כשמשתמשים בחלון פרטי מפוצל.
- כולל אזור אחסון מנוהל בלעדי לקריאה בלבד למדיניות ארגונית.
האם תוספים יכולים להשתמש בממשקי API של אחסון אינטרנט?
תוספים יכולים להשתמש בממשק Storage
(שאפשר לגשת אליו מ-window.localStorage
) בהקשרים מסוימים (חלונות קופצים ודפי HTML אחרים), אבל אנחנו לא ממליצים על כך מהסיבות הבאות:
- קובצי שירות (service workers) של תוספים לא יכולים להשתמש ב-Web Storage API.
- סקריפטים של תוכן חולקים את האחסון עם דף המארח.
- הנתונים שנשמרים באמצעות Web Storage API נמחקים כשהמשתמש מוחק את היסטוריית הגלישה שלו.
כדי להעביר נתונים מממשקי API של אחסון באינטרנט לממשקי API של אחסון תוספים מ-service worker:
- מכינים דף HTML של מסמך מחוץ למסך וקובץ סקריפט. קובץ הסקריפט צריך להכיל שגרת המרה ומטפל
onMessage
. - בודקים את
chrome.storage
ב-service worker של התוסף כדי לראות את הנתונים. - אם הנתונים לא נמצאו, צריך להתקשר אל
createDocument()
. - אחרי שה-Promise שמוחזר מסתיים, קוראים ל-
sendMessage()
כדי להתחיל את שגרת ההמרה. - בתוך ה-handler
onMessage
של המסמך מחוץ למסך, קוראים לשגרה של ההמרה.
יש גם כמה ניואנסים לגבי אופן הפעולה של ממשקי API לאחסון נתונים בדפדפן בתוספים. מידע נוסף זמין במאמר בנושא אחסון וקובצי Cookie.
אזורי אחסון
Storage API מחולק לאזורי האחסון הבאים:
storage.local
- הנתונים מאוחסנים באופן מקומי ונמחקים כשמסירים את התוסף. מגבלת האחסון היא 10MB (5MB ב-Chrome 113 ובגרסאות קודמות), אבל אפשר להגדיל אותה על ידי בקשת ההרשאה
"unlimitedStorage"
. מומלץ להשתמש ב-storage.local
כדי לאחסן כמויות גדולות יותר של נתונים. כברירת מחדל, הוא חשוף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי קריאה ל-chrome.storage.local.setAccessLevel()
. storage.managed
- אחסון מנוהל הוא אחסון לקריאה בלבד של תוספים שהותקנו לפי מדיניות, והוא מנוהל על ידי מנהלי מערכת באמצעות סכימה שהוגדרה על ידי מפתחים ומדיניות ארגונית. המדיניות דומה לאפשרויות, אבל אדמין מערכת מגדיר אותה במקום המשתמש. כך אפשר להגדיר מראש את התוסף לכל המשתמשים בארגון. מידע על מדיניות זמין במסמכי התיעוד לאדמינסטרטורים. מידע נוסף על אזור האחסון
managed
זמין במאמר Manifest לאזורי אחסון. storage.session
- שומר נתונים בזיכרון בזמן שהתוסף נטען. האחסון מתרוקן אם משביתים את התוסף, טוענים אותו מחדש או מעדכנים אותו, וגם כשמפעילים מחדש את הדפדפן. כברירת מחדל, הוא לא נחשף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי קריאה ל-
chrome.storage.session.setAccessLevel()
. מגבלת האחסון היא 10MB (1MB ב-Chrome 111 ובגרסאות קודמות). ממשקstorage.session
הוא אחד מכמה ממשקים שמומלצים ל-Service Worker. storage.sync
- אם הסנכרון מופעל, הנתונים מסונכרנים עם כל דפדפן Chrome שהמשתמש מחובר אליו. אם המדיניות מושבתת, ההתנהגות שלה זהה לזו של
storage.local
. Chrome שומר את הנתונים באופן מקומי כשהדפדפן במצב אופליין, וממשיך לסנכרן כשהוא חוזר למצב אונליין. מגבלת המכסה היא כ-100KB, 8KB לכל פריט. מומלץ להשתמש ב-storage.sync
כדי לשמור על הגדרות המשתמש בדפדפנים מסונכרנים. אם אתם עובדים עם נתוני משתמש רגישים, עדיף להשתמש ב-storage.session
. כברירת מחדל,storage.sync
נחשף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי קריאה ל-chrome.storage.sync.setAccessLevel()
.
מגבלות על נפח האחסון והגבלת קצב העברת הנתונים
אלו מגבלות השימוש ב-Storage API:
- אחסון נתונים כרוך בדרך כלל בעלויות שקשורות לביצועים, וב-API יש מכסות אחסון. מומלץ לשים לב אילו נתונים מאוחסנים כדי לא לאבד את היכולת לאחסן נתונים.
- יכול להיות שיעבור קצת זמן עד להשלמת הפעולה. חשוב לוודא שמבנה הקוד לוקח בחשבון את הזמן הזה.
פרטים על מגבלות נפח האחסון ומה קורה כשחורגים מהן מופיעים במידע על המכסות של sync
, local
ו-session
.
תרחישים לדוגמה
בקטעים הבאים מוצגות דוגמאות לתרחישי שימוש נפוצים ב-Storage 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
, וה-service worker משתמש ב-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);
}
});
טעינה מראש אסינכרונית מהאחסון
מאחר שסקריפט service worker לא פועל כל הזמן, לפעמים תוספים של Manifest V3 צריכים לטעון נתונים מהאחסון באופן אסינכרוני לפני שהם מפעילים את handlers של האירועים. לשם כך, בקטע הקוד הבא נעשה שימוש ב-handler אסינכרוני של אירוע 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 בכלי הפיתוח. מידע נוסף זמין במאמר הצגה ועריכה של אחסון נתונים של תוספים במסמכי התיעוד של כלי הפיתוח.
דוגמאות
בדוגמאות הבאות מוצגים אזורי האחסון local
, sync
ו-session
:
מקומי
chrome.storage.local.set({ key: value }).then(() => {
console.log("Value is set");
});
chrome.storage.local.get(["key"]).then((result) => {
console.log("Value is " + result.key);
});
סנכרון
chrome.storage.sync.set({ key: value }).then(() => {
console.log("Value is set");
});
chrome.storage.sync.get(["key"]).then((result) => {
console.log("Value is " + result.key);
});
סשן
chrome.storage.session.set({ key: value }).then(() => {
console.log("Value was set");
});
chrome.storage.session.get(["key"]).then((result) => {
console.log("Value is " + result.key);
});
כדי לראות הדגמות נוספות של Storage API, אפשר לעיין באחת מהדוגמאות הבאות:
סוגים
AccessLevel
רמת הגישה לאזור האחסון.
Enum
TRUSTED_CONTEXTS
מציין הקשרים שמקורם בתוסף עצמו.
"TRUSTED_AND_UNTRUSTED_CONTEXTS"
מציין הקשרים שמקורם מחוץ לתוסף.
StorageArea
מאפיינים
-
onChanged
Event<functionvoidvoid>
Chrome 73 ואילךהאירוע מופעל כשפריט אחד או יותר משתנים.
הפונקציה
onChanged.addListener
נראית כך:(callback: function) => {...}
-
callback
פונקציה
הפרמטר
callback
נראה כך:(changes: object) => void
-
שינויים
אובייקט
-
-
-
נקה
void
Promiseהסרת כל הפריטים מהאחסון.
הפונקציה
clear
נראית כך:(callback?: function) => {...}
-
callback
פונקציה אופציונלית
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
Chrome 95 ואילךיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל יש גם קריאות חוזרות (callbacks) לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. ההבטחה מסתיימת עם אותו סוג שמועבר לפונקציית הקריאה החוזרת.
-
-
get
void
Promiseמקבל פריט אחד או יותר מהאחסון.
הפונקציה
get
נראית כך:(keys?: string | string[] | object, callback?: function) => {...}
-
מפתחות
מחרוזת | מערך מחרוזות | אובייקט אופציונלי
מפתח יחיד להשגה, רשימת מפתחות להשגה או מילון שמציין ערכי ברירת מחדל (ראו תיאור של האובייקט). רשימה או אובייקט ריקים יחזירו אובייקט תוצאה ריק. מעבירים את
null
כדי לקבל את כל התוכן של האחסון. -
callback
פונקציה אופציונלית
הפרמטר
callback
נראה כך:(items: object) => void
-
פריטים
אובייקט
אובייקט עם פריטים במיפויי מפתח-ערך.
-
-
החזרות
Promise<object>
Chrome 95 ואילךיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל יש גם קריאות חוזרות (callbacks) לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. ההבטחה מסתיימת עם אותו סוג שמועבר לפונקציית הקריאה החוזרת.
-
-
getBytesInUse
void
Promiseהפונקציה מחזירה את כמות הנפח (בבייטים) שמשמשת פריט אחד או יותר.
הפונקציה
getBytesInUse
נראית כך:(keys?: string | string[], callback?: function) => {...}
-
מפתחות
מחרוזת | מערך מחרוזות אופציונלי
מפתח יחיד או רשימת מפתחות שרוצים לקבל את נתוני השימוש הכוללים שלהם. אם הרשימה ריקה, הפונקציה תחזיר 0. מעבירים את הערך
null
כדי לקבל את נפח האחסון הכולל בשימוש. -
callback
פונקציה אופציונלית
הפרמטר
callback
נראה כך:(bytesInUse: number) => void
-
bytesInUse
number
כמות המקום שנעשה בו שימוש באחסון, בבייטים.
-
-
החזרות
Promise<number>
Chrome 95 ואילךיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל יש גם קריאות חוזרות (callbacks) לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. ההבטחה מסתיימת עם אותו סוג שמועבר לפונקציית הקריאה החוזרת.
-
-
getKeys
void
Promise Chrome 130+אחזור כל המפתחות מהאחסון.
הפונקציה
getKeys
נראית כך:(callback?: function) => {...}
-
callback
פונקציה אופציונלית
הפרמטר
callback
נראה כך:(keys: string[]) => void
-
מפתחות
string[]
מערך עם מפתחות שנקראו מהאחסון.
-
-
החזרות
Promise<string[]>
יש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל יש גם קריאות חוזרות (callbacks) לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. ההבטחה מסתיימת עם אותו סוג שמועבר לפונקציית הקריאה החוזרת.
-
-
remove
void
Promiseהסרה של פריט אחד או יותר מהאחסון.
הפונקציה
remove
נראית כך:(keys: string | string[], callback?: function) => {...}
-
מפתחות
מחרוזת | מחרוזת[]
מפתח יחיד או רשימת מפתחות של פריטים להסרה.
-
callback
פונקציה אופציונלית
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
Chrome 95 ואילךיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל יש גם קריאות חוזרות (callbacks) לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. ההבטחה מסתיימת עם אותו סוג שמועבר לפונקציית הקריאה החוזרת.
-
-
הוגדר
void
Promiseהגדרת כמה פריטים.
הפונקציה
set
נראית כך:(items: object, callback?: function) => {...}
-
פריטים
אובייקט
אובייקט שכולל כל צמד מפתח/ערך לעדכון האחסון. צמדי מפתח/ערך אחרים באחסון לא יושפעו.
ערכים פרימיטיביים כמו מספרים יעברו סריאליזציה כמצופה. ערכים עם
typeof
"object"
ו-"function"
בדרך כלל יעברו סריאליזציה ל-{}
, למעטArray
(עובר סריאליזציה כצפוי),Date
ו-Regex
(עוברים סריאליזציה באמצעות הייצוג שלהם ב-String
). -
callback
פונקציה אופציונלית
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
Chrome 95 ואילךיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל יש גם קריאות חוזרות (callbacks) לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. ההבטחה מסתיימת עם אותו סוג שמועבר לפונקציית הקריאה החוזרת.
-
-
setAccessLevel
void
Promise Chrome 102+מגדירים את רמת הגישה הרצויה לאזור האחסון. כברירת מחדל, הגישה לאחסון של
session
מוגבלת להקשרים מהימנים (דפי תוספים וקובצי שירות), בעוד שהגישה לאחסון שלlocal
ושלsync
מותרת גם מהקשרים מהימנים וגם מהקשרים לא מהימנים.הפונקציה
setAccessLevel
נראית כך:(accessOptions: object, callback?: function) => {...}
-
accessOptions
אובייקט
-
accessLevel
רמת הגישה לאזור האחסון.
-
-
callback
פונקציה אופציונלית
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
יש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל יש גם קריאות חוזרות (callbacks) לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. ההבטחה מסתיימת עם אותו סוג שמועבר לפונקציית הקריאה החוזרת.
-
StorageChange
מאפיינים
-
newValue
כל מאפיין אופציונלי
הערך החדש של הפריט, אם יש ערך חדש.
-
oldValue
כל מאפיין אופציונלי
הערך הקודם של הפריט, אם היה ערך קודם.
מאפיינים
local
הפריטים באזור האחסון local
הם מקומיים לכל מכונה.
סוג
StorageArea ו-object
מאפיינים
-
QUOTA_BYTES
10485760
הכמות המקסימלית (בבייטים) של נתונים שאפשר לאחסן באחסון מקומי, כפי שנמדדת על ידי המרת כל ערך למחרוזת JSON בתוספת האורך של כל מפתח. המערכת תתעלם מהערך הזה אם לתוסף יש הרשאה מסוג
unlimitedStorage
. עדכונים שיגרמו לחריגה מהמגבלה הזו ייכשלו באופן מיידי ויגדירו אתruntime.lastError
אם משתמשים בפונקציית קריאה חוזרת, או Promise שנדחה אם משתמשים ב-async/await.
managed
הפריטים באזור האחסון managed
מוגדרים על ידי מדיניות ארגונית שהוגדרה על ידי האדמין של הדומיין, והם לקריאה בלבד עבור התוסף. ניסיון לשנות את מרחב השמות הזה יגרום לשגיאה. מידע על הגדרת מדיניות זמין במאמר קובץ מניפסט לאזורי אחסון.
סוג
session
פריטים באזור האחסון session
מאוחסנים בזיכרון ולא נשמרים בדיסק.
סוג
StorageArea ו-object
מאפיינים
-
QUOTA_BYTES
10485760
הכמות המקסימלית (בבייטים) של נתונים שאפשר לאחסן בזיכרון, שנמדדת על ידי הערכת השימוש בזיכרון שהוקצה באופן דינמי לכל ערך ומפתח. עדכונים שיגרמו לחריגה מהמגבלה הזו ייכשלו באופן מיידי ויגדירו את
runtime.lastError
כשמשתמשים בפונקציית קריאה חוזרת, או כשדחייה של Promise מתרחשת.
sync
פריטים באזור האחסון sync
מסונכרנים באמצעות סנכרון Chrome.
סוג
StorageArea ו-object
מאפיינים
-
MAX_ITEMS
512
מספר הפריטים המקסימלי שאפשר לאחסן באחסון הסנכרון. עדכונים שיגרמו לחריגה מהמגבלה הזו ייכשלו באופן מיידי ויגדירו את
runtime.lastError
כשמשתמשים בפונקציית קריאה חוזרת (callback) או כשדחיית Promise. -
MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE
1000000
הוצא משימושל-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
כשמשתמשים בפונקציית קריאה חוזרת (callback) או כשדחיית הבטחה (Promise) מתרחשת.
אירועים
onChanged
chrome.storage.onChanged.addListener(
callback: function,
)
האירוע מופעל כשפריט אחד או יותר משתנים.
פרמטרים
-
callback
פונקציה
הפרמטר
callback
נראה כך:(changes: object, areaName: string) => void
-
שינויים
אובייקט
-
areaName
מחרוזת
-