תיאור
אפשר להשתמש ב-API chrome.storage
כדי לאחסן נתוני משתמשים, לאחזר אותם ולעקוב אחריהם.
הרשאות
storage
סקירה כללית
Storage API מספק דרך ספציפית לתוסף לשמור נתונים ומצבים של משתמשים. היא דומה לממשקי ה-API לאחסון של פלטפורמת האינטרנט (IndexedDB ו-Storage), אבל היא תוכננה לענות על צורכי האחסון של תוספים. אלה כמה מהתכונות העיקריות:
- לכל ההקשרים של התוספים, כולל קובץ השירות (service worker) של התוסף וסקריפטים של התוכן, יש גישה ל-Storage API.
- הערכים שניתן להציג בסדרה של JSON מאוחסנים כמאפייני אובייקט.
- Storage API הוא אסינכרוני עם פעולות של קריאה וכתיבה בכמות גדולה.
- גם אם המשתמש מנקה את המטמון ואת היסטוריית הגלישה, הנתונים ממשיכים.
- ההגדרות השמורות נשמרות גם כשמשתמשים בפיצול במצב פרטי.
- כולל אזור אחסון מנוהל בלעדי לקריאה בלבד למדיניות הארגון.
תוספים יכולים להשתמש בממשק [Storage
][mdn-storage] (נגיש מ-window.localStorage
) בהקשרים מסוימים (חלון קופץ ודפי HTML אחרים), אבל הוא לא מומלץ מהסיבות הבאות:
- קובץ השירות (service worker) של התוסף לא יכול לגשת אל
Storage
. - סקריפטים של תוכן חולקים את האחסון עם הדף המארח.
- נתונים שנשמרים באמצעות הממשק
Storage
אובדים כשהמשתמש מנקה את היסטוריית הגלישה שלו.
כדי להעביר נתונים מממשקי API לאחסון באינטרנט לממשקי API לאחסון תוספים מ-Service Worker:
- יצירת מסמך מחוץ למסך באמצעות תרחיש המרות ו-handler [
onMessage
][on-message]. - הוספת תרחיש המרה למסמך שלא מופיע במסך.
- ב-Service Worker של התוסף בודקים את הנתונים ב-
chrome.storage
. - אם הנתונים שלך לא נמצאו, [create][create-offscreen] מסמך שלא מופיע במסך וצריך להתקשר למספר [
sendMessage()
][send-message] כדי להתחיל את תרחיש ההמרות. - בתוך ה-handler של
onMessage
של המסמך מחוץ למסך, מפעילים את תרחיש ההמרה.
יש גם כמה ניואנסים באופן הפעולה של ממשקי API לאחסון באינטרנט בתוספים. מידע נוסף מופיע במאמר [אחסון וקובצי cookie][storage-and-cookies].
אזורי אחסון
ה-Storage API מחולק לארבע הקטגוריות הבאות ("אזורי אחסון"):
storage.local
- נתונים מאוחסנים באופן מקומי, והם נמחקים כשהתוסף מוסר. המכסה היא כ-10MB, אבל אפשר להגדיל אותה באמצעות בקשת ההרשאה
"unlimitedStorage"
. כדאי להשתמש בה כדי לאחסן כמויות גדולות יותר של נתונים.
storage.sync
- אם הסנכרון מופעל, הנתונים יסונכרנו לכל דפדפן Chrome שאליו המשתמש מחובר. אם המדיניות מושבתת, ההתנהגות שלה תהיה זהה לזו של
storage.local
. Chrome מאחסן את הנתונים באופן מקומי כשהדפדפן במצב אופליין וממשיך את הסנכרון כשהוא חוזר למצב מקוון. המגבלה המקסימלית היא 100KB, 8KB לכל פריט. כדאי להשתמש בה כדי לשמור את הגדרות המשתמשים בכל הדפדפנים המסונכרנים.
- storage.session
- שמירת הנתונים בזיכרון במהלך סשן בדפדפן. כברירת מחדל, ה-API לא חשוף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי הגדרה של
chrome.storage.session.setAccessLevel()
. המגבלה המקסימלית היא כ-10MB. כדאי להשתמש בו כדי לאחסן משתנים גלובליים כשמפעילים את קובץ השירות (service worker).
- storage.managed
- אדמינים יכולים להשתמש בסכימה ובמדיניות ארגונית כדי לקבוע הגדרות של תוסף תומך בסביבה מנוהלת. אזור האחסון הזה הוא לקריאה בלבד.
מניפסט
כדי להשתמש ב-Storage API, מצהירים על ההרשאה "storage"
במניפסט של התוסף. למשל:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
Usage
בדוגמאות הבאות אפשר לראות את אזורי האחסון 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
זמין במאמר מניפסט לאזורי אחסון.
מגבלות אחסון וויסות נתונים
אל תחשוב שהוספה ל-Storage 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 Workers לא תמיד פועלים, תוספי Manifest V3 צריכים לפעמים לטעון נתונים מהאחסון באופן אסינכרוני לפני שהם מפעילים את הגורמים המטפלים באירועים. כדי לעשות זאת, קטע הקוד הבא משתמש ב-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);
});
דוגמאות לתוספים
כדי לראות הדגמות נוספות של Storage API, תוכלו להיעזר בדוגמאות הבאות:
סוגים
AccessLevel
רמת הגישה של אזור האחסון.
טיפוסים בני מנייה (enum)
"TRUSTED_CONTEXTS"
מציין הקשרים שמקורם בתוסף עצמו.
"TRUSTED_AND_UNTRUSTED_CONTEXTS"
מציין הקשרים שמקורם מחוץ לתוסף.
StorageArea
תכונות
-
onChanged
אירוע<functionvoidvoid>
Chrome 73 ומעלהמופעל כשפריט אחד או יותר משתנים.
הפונקציה
onChanged.addListener
נראית כך:(callback: function) => {...}
-
קריאה חוזרת (callback)
פונקציה
הפרמטר
callback
נראה כך:(changes: object) => void
-
שינויים
אובייקט
-
-
-
מחיקה
void
הבטחהכל הפריטים יוסרו מהאחסון.
הפונקציה
clear
נראית כך:(callback?: function) => {...}
-
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
Chrome 88 ומעלההבטחות נתמכות רק במניפסט מגרסה V3 ואילך. בפלטפורמות אחרות צריך להשתמש בקריאות חוזרות (callback).
-
-
get
void
הבטחהמקבלת פריט אחד או יותר מנפח האחסון.
הפונקציה
get
נראית כך:(keys?: string | string[] | object, callback?: function) => {...}
-
מפתחות
string | string[] | אובייקט אופציונלי
מפתח יחיד לקבל, רשימת מפתחות לקבל או מילון שמציין ערכי ברירת מחדל (ראו תיאור של האובייקט). רשימה או אובייקט ריקים יחזירו אובייקט תוצאה ריק. עוברים אל
null
כדי לקבל את כל נפח האחסון. -
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:(items: object) => void
-
items
אובייקט
אובייקט עם פריטים במיפויים של מפתח-ערך.
-
-
החזרות
Promise<object>
Chrome 88 ומעלההבטחות נתמכות רק במניפסט מגרסה V3 ואילך. בפלטפורמות אחרות צריך להשתמש בקריאות חוזרות (callback).
-
-
getBytesInUse
void
הבטחההפונקציה מקבלת את נפח האחסון (בבייטים) שמשמש פריט אחד או יותר.
הפונקציה
getBytesInUse
נראית כך:(keys?: string | string[], callback?: function) => {...}
-
מפתחות
string | string[] אופציונלי
מפתח יחיד או רשימת מפתחות שעבורם תקבלו את סך השימוש. רשימה ריקה תחזיר את הערך 0. כדאי להעביר
null
כדי לנצל את כל נפח האחסון. -
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:(bytesInUse: number) => void
-
bytesInUse
number
נפח האחסון שנוצל באחסון, בבייטים.
-
-
החזרות
הבטחה<number>
Chrome 88 ומעלההבטחות נתמכות רק במניפסט מגרסה V3 ואילך. בפלטפורמות אחרות צריך להשתמש בקריאות חוזרות (callback).
-
-
remove
void
הבטחההסרה של פריט אחד או יותר מנפח האחסון.
הפונקציה
remove
נראית כך:(keys: string | string[], callback?: function) => {...}
-
מפתחות
מחרוזת | string[]
מפתח יחיד או רשימת מפתחות לפריטים להסרה.
-
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
Chrome 88 ומעלההבטחות נתמכות רק במניפסט מגרסה V3 ואילך. בפלטפורמות אחרות צריך להשתמש בקריאות חוזרות (callback).
-
-
הוגדר
void
הבטחהמגדיר מספר פריטים.
הפונקציה
set
נראית כך:(items: object, callback?: function) => {...}
-
items
אובייקט
אובייקט שמספק כל צמד מפתח/ערך לעדכון האחסון. צמדי מפתח/ערך אחרים באחסון לא יושפעו.
ערכים פרימיטיביים, כמו מספרים, יופיעו בהמשכים כמצופה. ערכים עם
typeof
"object"
ו-"function"
יופיעו בדרך כלל בסדרה כ-{}
, מלבדArray
(הצגה סריאלית כמצופה),Date
ו-Regex
(סריאלית באמצעות ייצוגString
שלהם). -
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
Chrome 88 ומעלההבטחות נתמכות רק במניפסט מגרסה V3 ואילך. בפלטפורמות אחרות צריך להשתמש בקריאות חוזרות (callback).
-
-
setAccessLevel
void
Promise Chrome 102 ואילךמגדירה את רמת הגישה הרצויה לאזור האחסון. ברירת המחדל תהיה רק הקשרים מהימנים.
הפונקציה
setAccessLevel
נראית כך:(accessOptions: object, callback?: function) => {...}
-
accessOptions
אובייקט
-
accessLevel
רמת גישה באזור האחסון.
-
-
קריאה חוזרת (callback)
פונקציה אופציונלי
הפרמטר
callback
נראה כך:() => void
-
החזרות
Promise<void>
הבטחות נתמכות רק במניפסט מגרסה V3 ואילך. בפלטפורמות אחרות צריך להשתמש בקריאות חוזרות (callback).
-
StorageChange
תכונות
-
newValue
כל אופציונלי
הערך החדש של הפריט, אם יש ערך חדש.
-
oldValue
כל אופציונלי
הערך הישן של הפריט, אם היה ערך ישן.
תכונות
local
הפריטים באזור האחסון של local
מותאמים לכל מכונה מקומית.
סוג
StorageArea ואובייקט
תכונות
-
QUOTA_BYTES
10485760
הכמות המקסימלית (בבייטים) של נתונים שניתן לאחסן באחסון מקומי, לפי מדידה באמצעות מחרוזת JSON של כל ערך ושל האורך של כל מפתח. המערכת תתעלם מהערך הזה אם לתוסף יש את ההרשאה
unlimitedStorage
. עדכונים שגורמים לחריגה מהמגבלה הזו נכשלים באופן מיידי ומגדירים את הערךruntime.lastError
כשמשתמשים בקריאה חוזרת (callback), או בהבטחה שנדחתה אם משתמשים בפונקציה async/await.
managed
פריטים באזור האחסון של managed
מוגדרים על ידי מדיניות ארגונית שהוגדרה על ידי מנהל הדומיין, והם מוגדרים לקריאה בלבד עבור התוסף. ניסיון לשנות את מרחב השמות הזה יוביל לשגיאה. מידע נוסף על הגדרת מדיניות זמין במאמר מניפסט לאזורי אחסון.
סוג
session
הפריטים שבאזור האחסון של session
מאוחסנים בזיכרון ולא יישמרו בדיסק.
סוג
StorageArea ואובייקט
תכונות
-
QUOTA_BYTES
10485760
הכמות המקסימלית (בבייטים) של נתונים שאפשר לאחסן בזיכרון, שנמדדת על ידי הערכת השימוש הדינמי בזיכרון שמוקצה באופן דינמי לכל ערך ומפתח. עדכונים שעלולים לגרום לחריגה מהמגבלה הזו נכשלים באופן מיידי ומגדירים את
runtime.lastError
במהלך השימוש בקריאה חוזרת (callback) או במקרה של דחייה של Promise (הבטחה).
sync
פריטים באזור האחסון של sync
מסונכרנים באמצעות סנכרון Chrome.
סוג
StorageArea ואובייקט
תכונות
-
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
string
-