תיאור
שימוש ב-API של chrome.storage
כדי לאחסן, לאחזר ולעקוב אחרי שינויים בנתוני משתמשים.
הרשאות
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 אחרים), אבל אנחנו לא ממליצים על כך מהסיבות הבאות:
- קובצי שירות של תוספים לא יכולים להשתמש ב-Web Storage API.
- סקריפטים של תוכן משתפים את נפח האחסון עם הדף המארח.
- נתונים שנשמרו באמצעות Web Storage API הולכים לאיבוד כשהמשתמש מנקה את היסטוריית הגלישה.
כדי להעביר נתונים ממשקי API לאחסון באינטרנט לממשקי API לאחסון בתוספים מ-service worker:
- מכינים דף HTML וקובץ סקריפט של מסמך מחוץ למסך. קובץ הסקריפט צריך להכיל תוכנית המרה וטיפול באירוע
onMessage
. - ב-service worker של התוסף, בודקים את
chrome.storage
כדי למצוא את הנתונים. - אם הנתונים לא נמצאים, צריך להתקשר למספר
createDocument()
. - אחרי שה-Promise שהוחזר יתקבל, צריך לבצע קריאה ל-
sendMessage()
כדי להפעיל את תרגיל ההמרות. - בתוך הטיפול
onMessage
של המסמך מחוץ למסך, קוראים לתוכנית ההמרה.
יש גם כמה ניואנסים לגבי האופן שבו ממשקי API לאחסון באינטרנט פועלים בתוספים. מידע נוסף זמין במאמר אחסון וקובצי cookie.
אזורי אחסון
Storage API מחולק לאזורי האחסון הבאים:
storage.local
- הנתונים נשמרים באופן מקומי ונמחקים כשהתוסף מוסר. מגבלת האחסון היא 10MB (5MB ב-Chrome 113 וגרסאות קודמות), אבל אפשר להגדיל אותה על ידי בקשה להרשאה
"unlimitedStorage"
. מומלץ להשתמש ב-storage.local
כדי לאחסן כמויות גדולות יותר של נתונים. storage.managed
- אחסון מנוהל הוא אחסון לקריאה בלבד של תוספים שהותקנו לפי מדיניות, ומנוהל על ידי אדמינים של מערכות באמצעות סכימות שהוגדרו על ידי מפתחים ומדיניות ארגונית. כללי המדיניות דומים לאפשרויות, אבל הם מוגדרים על ידי אדמין מערכת במקום על ידי המשתמש, ומאפשרים להגדיר מראש את התוסף לכל המשתמשים בארגון. מידע על כללי המדיניות זמין במאמר מסמכי עזרה לאדמינים. מידע נוסף על אזור האחסון
managed
זמין במאמר מאניפסט לאזורי אחסון. storage.session
- שמירת נתונים בזיכרון למשך סשן הדפדפן. כברירת מחדל, הוא לא חשוף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי הגדרת
chrome.storage.session.setAccessLevel()
. מגבלת האחסון היא 10MB (1MB ב-Chrome 111 וגרסאות קודמות). הממשקstorage.session
הוא אחד מכמה ממשקים שאנחנו ממליצים לשימוש בשירותי עבודה. storage.sync
- אם הסנכרון מופעל, הנתונים מסתנכרנים עם כל דפדפן Chrome שאליו המשתמש מחובר. אם המדיניות מושבתת, היא פועלת כמו
storage.local
. Chrome שומר את הנתונים באופן מקומי כשהדפדפן במצב אופליין, וממשיך את הסנכרון כשהדפדפן חוזר לאינטרנט. מגבלת המכסה היא כ-100KB, 8KB לכל פריט. מומלץ להשתמש ב-storage.sync
כדי לשמור את הגדרות המשתמש בדפדפנים מסונכרנים. אם אתם עובדים עם נתוני משתמש רגישים, השתמשו במקום זאת ב-storage.session
.
מגבלות אחסון והגבלות על קצב העברת הנתונים
אלה המגבלות על השימוש ב-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);
}
});
טעינה אסינכרונית מראש מהאחסון
מאחר ששירותי ה-Worker לא פועלים כל הזמן, לפעמים תוספים של 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);
});
דוגמאות
בדוגמאות הבאות מוצגים אזורי האחסון 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>
גרסה 88 ואילך של Chromeיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל פונקציות קריאה חוזרת (callbacks) ניתנות לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. הפתרון של ההבטחה יהיה באותו סוג שהוענק ל-callback.
-
-
get
void
Promiseאחזור פריט אחד או יותר מהאחסון.
הפונקציה
get
נראית כך:(keys?: string | string[] | object, callback?: function) => {...}
-
מפתחות
string | string[] | object אופציונלי
מפתח יחיד לאחזור, רשימת מפתחות לאחזור או מילון שמציין ערכי ברירת מחדל (ראו תיאור האובייקט). רשימה או אובייקט ריקים יחזירו אובייקט תוצאה ריק. מעבירים את הערך
null
כדי לקבל את כל התוכן של האחסון. -
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:(items: object) => void
-
פריטים
אובייקט
אובייקט עם פריטים במיפויים של מפתח-ערך.
-
-
החזרות
Promise<object>
גרסה 88 ואילך של Chromeיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל פונקציות קריאה חוזרת (callbacks) ניתנות לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. הפתרון של ההבטחה יהיה באותו סוג שהוענק ל-callback.
-
-
getBytesInUse
void
Promiseהפונקציה מקבלת את נפח האחסון (בבייטים) שפריטים אחדים או יותר משתמשים בו.
הפונקציה
getBytesInUse
נראית כך:(keys?: string | string[], callback?: function) => {...}
-
מפתחות
מחרוזת | מחרוזות אופציונלי
מפתח יחיד או רשימה של מפתחות שעבורם רוצים לקבל את סך כל השימוש. רשימה ריקה תחזיר את הערך 0. מעבירים את הערך
null
כדי לקבל את השימוש הכולל בכל נפח האחסון. -
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:(bytesInUse: number) => void
-
bytesInUse
number
נפח האחסון שנמצא בשימוש, בבייט.
-
-
החזרות
Promise<number>
גרסה 88 ואילך של Chromeיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל פונקציות קריאה חוזרת (callbacks) ניתנות לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. הפתרון של ההבטחה יהיה באותו סוג שהוענק ל-callback.
-
-
getKeys
void
Promise Chrome מגרסה 130 ואילךאחזור כל המפתחות מהאחסון.
הפונקציה
getKeys
נראית כך:(callback?: function) => {...}
-
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:(keys: string[]) => void
-
מפתחות
string[]
מערך עם מפתחות שנקראו מהאחסון.
-
-
החזרות
Promise<string[]>
יש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל פונקציות קריאה חוזרת (callbacks) ניתנות לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. הפתרון של ההבטחה יהיה באותו סוג שהוענק ל-callback.
-
-
remove
void
Promiseהסרה של פריט אחד או יותר מהאחסון.
הפונקציה
remove
נראית כך:(keys: string | string[], callback?: function) => {...}
-
מפתחות
string | string[]
מפתח יחיד או רשימת מפתחות לפריטים להסרה.
-
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
גרסה 88 ואילך של Chromeיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל פונקציות קריאה חוזרת (callbacks) ניתנות לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. הפתרון של ההבטחה יהיה באותו סוג שהוענק ל-callback.
-
-
הוגדר
void
Promiseהגדרת מספר פריטים.
הפונקציה
set
נראית כך:(items: object, callback?: function) => {...}
-
פריטים
אובייקט
אובייקט שמספק לכל זוג מפתח/ערך את הנתונים לעדכון האחסון. שום צמד מפתח/ערך אחר באחסון לא יושפע.
ערכים פרימיטיביים כמו מספרים יסריאליזציה כצפוי. ערכים עם
typeof
"object"
ו-"function"
יסריאליזציה בדרך כלל ל-{}
, מלבדArray
(הסריאליזציה מתבצעת כצפוי),Date
ו-Regex
(הסריאליזציה מתבצעת באמצעות הייצוג שלהם ב-String
). -
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
גרסה 88 ואילך של Chromeיש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל פונקציות קריאה חוזרת (callbacks) ניתנות לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. הפתרון של ההבטחה יהיה באותו סוג שהוענק ל-callback.
-
-
setAccessLevel
void
Promise Chrome מגרסה 102 ואילךהגדרת רמת הגישה הרצויה לאזור האחסון. כברירת מחדל, יוצגו רק הקשרים המהימנים.
הפונקציה
setAccessLevel
נראית כך:(accessOptions: object, callback?: function) => {...}
-
accessOptions
אובייקט
-
accessLevel
רמת הגישה של אזור האחסון.
-
-
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
יש תמיכה ב-Promises ב-Manifest V3 ואילך, אבל פונקציות קריאה חוזרת (callbacks) ניתנות לצורך תאימות לאחור. אי אפשר להשתמש בשניהם באותה קריאה לפונקציה. הפתרון של ההבטחה יהיה באותו סוג שהוענק ל-callback.
-
StorageChange
מאפיינים
-
newValue
כל אופציונלי
הערך החדש של הפריט, אם יש ערך חדש.
-
oldValue
כל אופציונלי
הערך הישן של הפריט, אם היה ערך ישן.
מאפיינים
local
הפריטים באזור האחסון local
הם מקומיים לכל מכונה.
סוג
StorageArea ו-object
מאפיינים
-
QUOTA_BYTES
10485760
הכמות המקסימלית (בייטים) של נתונים שאפשר לאחסן באחסון המקומי, כפי שנמדדת על ידי המחרוזת של ה-JSON של כל ערך בתוספת אורך כל מפתח. המערכת תתעלם מהערך הזה אם לתוסף יש את ההרשאה
unlimitedStorage
. עדכונים שגורמים לחריגה מהמגבלה הזו נכשלים באופן מיידי ומגדירים את הערךruntime.lastError
כשמשתמשים ב-callback, או Promise שנדחה אם משתמשים ב-async/await.
managed
הפריטים באזור האחסון managed
מוגדרים על ידי מדיניות ארגונית שמוגדרת על ידי האדמין של הדומיין, והם קריאה בלבד עבור התוסף. ניסיון לשנות את מרחב השמות הזה גורם לשגיאה. מידע נוסף על הגדרת מדיניות זמין במאמר מאניפסט לאזורי אחסון.
סוג
session
הפריטים באזור האחסון session
מאוחסנים בזיכרון ולא נשמרים בדיסק.
סוג
StorageArea ו-object
מאפיינים
-
QUOTA_BYTES
10485760
הכמות המקסימלית (בבייטים) של נתונים שאפשר לאחסן בזיכרון, כפי שנמדדת על ידי הערכת השימוש בזיכרון שהוקצה באופן דינמי לכל ערך ומפתח. עדכונים שגורמים לחריגה מהמגבלה הזו נכשלים באופן מיידי ומגדירים את הערך
runtime.lastError
כשמשתמשים בקריאה חוזרת (callback), או כש-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
שניתן לבצע בכל שעה. כלומר, פעולה אחת כל 2 שניות, מגבלה נמוכה יותר מהמגבלה הגבוהה יותר לכתיבה בדקה לטווח קצר.עדכונים שגורמים לחריגה מהמגבלה הזו נכשלים באופן מיידי ומגדירים את הערך
runtime.lastError
כשמשתמשים בקריאה חוזרת (callback), או כש-Promise נדחה. -
MAX_WRITE_OPERATIONS_PER_MINUTE
120
המספר המקסימלי של פעולות
set
,remove
אוclear
שניתן לבצע בכל דקה. זהו קצב של 2 שניות, שמספק תפוקת נתונים גבוהה יותר מאשר כתיבת בשעה בפרק זמן קצר יותר.עדכונים שגורמים לחריגה מהמגבלה הזו נכשלים באופן מיידי ומגדירים את הערך
runtime.lastError
כשמשתמשים בקריאה חוזרת (callback), או כש-Promise נדחה. -
QUOTA_BYTES
102400
הכמות הכוללת המקסימלית (בבייטים) של נתונים שאפשר לאחסן במאגר הסנכרון, כפי שנמדדת על ידי המחרוזת של ה-JSON של כל ערך בתוספת אורך כל מפתח. עדכונים שגורמים לחריגה מהמגבלה הזו נכשלים באופן מיידי ומגדירים את הערך
runtime.lastError
כשמשתמשים בקריאה חוזרת (callback), או כש-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
מחרוזת
-