browser.storage

תיאור

אפשר להשתמש ב-API של chrome.storage כדי לאחסן, לאחזר ולעקוב אחרי שינויים בנתוני המשתמשים.

הרשאות

storage

כדי להשתמש ב-storage API, צריך להצהיר על ההרשאה "storage" במניפסט של התוסף. לדוגמה:

{
  "name": "My extension",
  ...
  "permissions": [
    "storage"
  ],
  ...
}

דוגמאות

הדוגמאות הבאות ממחישות את אזורי האחסון local, sync ו-session:

דוגמה (מקומי)

await browser.storage.local.set({ key: value });
console.log("Value is set");
const result = await browser.storage.local.get(["key"]);
console.log("Value is " + result.key);

דוגמה (סנכרון)

await browser.storage.sync.set({ key: value });
console.log("Value is set");
const result = await browser.storage.sync.get(["key"]);
console.log("Value is " + result.key);

דוגמה (סשן)

await browser.storage.session.set({ key: value });
console.log("Value is set");
const result = await browser.storage.session.get(["key"]);
console.log("Value is " + result.key);

כדי לראות הדגמות אחרות של Storage API, אפשר לעיין בדוגמאות הבאות:

מושגים ושימוש

‫Storage API מספק דרך ספציפית לתוסף לשמור את נתוני המשתמשים ואת המצב שלהם. הוא דומה לממשקי ה-API לאחסון של פלטפורמת האינטרנט (IndexedDB ו-Storage), אבל הוא תוכנן כדי לענות על צורכי האחסון של תוספים. הנה כמה מהתכונות העיקריות:

  • לכל ההקשרים של התוסף, כולל ה-service worker של התוסף והסקריפטים של התוכן, יש גישה ל-Storage API.
  • הערכים שניתנים להמרה ל-JSON נשמרים כמאפייני אובייקט.
  • ‫Storage API הוא אסינכרוני עם פעולות קריאה וכתיבה בכמות גדולה.
  • גם אם המשתמש מנקה את המטמון ואת היסטוריית הגלישה, הנתונים נשמרים.
  • ההגדרות שנשמרו נשארות גם כשמשתמשים במצב פרטי מפוצל.
  • כולל אזור אחסון מנוהל לקריאה בלבד, שמיועד למדיניות ארגונית.

האם תוספים יכולים להשתמש בממשקי API של אחסון באינטרנט?

תוספים יכולים להשתמש בממשק Storage (שאפשר לגשת אליו דרך window.localStorage) בהקשרים מסוימים (חלונות קופצים ודפי HTML אחרים), אבל אנחנו לא ממליצים על כך מהסיבות הבאות:

  • קובצי Service Worker של תוספים לא יכולים להשתמש ב-Web Storage API.
  • סקריפטים של תוכן חולקים את נפח האחסון עם הדף המארח.
  • נתונים שנשמרים באמצעות Web Storage API נמחקים כשהמשתמש מוחק את היסטוריית הגלישה שלו.

כדי להעביר נתונים מממשקי API של אחסון באינטרנט לממשקי API של אחסון בתוספים מ-Service Worker:

  1. מכינים דף HTML וקובץ סקריפט של מסמך מחוץ למסך. קובץ הסקריפט צריך להכיל שגרת המרה ו-handler של onMessage.
  2. ב-Service Worker של התוסף, בודקים את הנתונים ב-browser.storage.
  3. אם הנתונים שלכם לא נמצאו, התקשרו למספר createDocument().
  4. אחרי שה-Promise שמוחזר נפתר, קוראים ל-sendMessage() כדי להתחיל את שגרת ההמרה.
  5. בתוך ה-handler של onMessage במסמך מחוץ למסך, מפעילים את שגרת ההמרה.

יש גם כמה הבדלים באופן שבו ממשקי API לאחסון באינטרנט פועלים בתוספים. מידע נוסף זמין במאמר אחסון וקובצי Cookie.

מגבלות אחסון וויסות נתונים

ל-Storage API יש מגבלות שימוש:

  • לאחסון נתונים יש עלויות ביצועים, וה-API כולל מכסות אחסון. תכננו את הנתונים שאתם מתכוונים לאחסן, כדי לשמור על נפח האחסון.
  • יכול להיות שיעבור קצת זמן עד שהאחסון יסתיים. צריך להביא בחשבון את הזמן הזה כשמגדירים את הקוד.

לפרטים על המגבלות של אזורי האחסון ומה קורה כשחורגים מהן, אפשר לעיין במידע על המכסות של sync,‏ local ו-session.

אזורי אחסון

‫Storage API מחולק לאזורי האחסון הבאים:

מקומי

הנתונים נשמרים באופן מקומי ונמחקים כשהתוסף מוסר. מגבלת האחסון היא 10MB‏ (5MB ב-Chrome 113 ובגרסאות קודמות), אבל אפשר להגדיל אותה על ידי בקשת ההרשאה "unlimitedStorage". מומלץ להשתמש ב-storage.local כדי לאחסן כמויות גדולות יותר של נתונים. כברירת מחדל, הוא חשוף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי קריאה ל-browser.storage.local.setAccessLevel().

מנוהל

האחסון המנוהל מוגדר לקריאה בלבד בתוספים שמותקנים לפי מדיניות. הוא מנוהל על ידי מנהלי מערכת, באמצעות סכימה שמוגדרת על ידי מפתחים וכללי מדיניות ארגוניים. כללי מדיניות דומים לאפשרויות, אבל הם מוגדרים על ידי אדמין במערכת ולא על ידי המשתמש. כך אפשר להגדיר מראש את התוסף לכל המשתמשים בארגון.

כברירת מחדל, storage.managed חשוף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי קריאה ל-browser.storage.managed.setAccessLevel(). מידע נוסף על כללי מדיניות זמין במסמכי התיעוד לאדמינים. מידע נוסף על אזור האחסון managed זמין במאמר מניפסט לאזורי אחסון.

סשן

אחסון הסשן שומר נתונים בזיכרון בזמן שהתוסף נטען. האחסון מתרוקן אם התוסף מושבת, נטען מחדש או מתעדכן, וכשהדפדפן מופעל מחדש. כברירת מחדל, הוא לא חשוף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי קריאה ל-browser.storage.session.setAccessLevel(). מגבלת האחסון היא 10MB‏ (1MB ב-Chrome 111 ובגרסאות קודמות).

ממשק storage.session הוא אחד מכמה ממשקים שאנחנו ממליצים עליהם ל-Service Worker.

סנכרון

אם המשתמש מפעיל את הסנכרון, הנתונים מסתנכרנים עם כל דפדפן Chrome שהמשתמש מחובר אליו. אם המדיניות מושבתת, ההתנהגות תהיה כמו במדיניות storage.local. ‫Chrome מאחסן את הנתונים באופן מקומי כשהדפדפן במצב אופליין, וממשיך את הסנכרון כשהוא חוזר למצב אונליין. מגבלת המכסה היא בערך 100KB, ‏ 8KB לכל פריט.

אנחנו ממליצים להשתמש ב-storage.sync כדי לשמור את הגדרות המשתמש בדפדפנים מסונכרנים. אם אתם עובדים עם נתוני משתמשים רגישים, השתמשו ב-storage.session. כברירת מחדל, storage.sync חשוף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי קריאה ל-browser.storage.sync.setAccessLevel().

שיטות ואירועים

כל אזורי האחסון מטמיעים את הממשק StorageArea.

get()‎

ה-method‏ get() מאפשרת לקרוא מפתח אחד או יותר מ-StorageArea.

getBytesInUse()‎

ה-method‏ getBytesInUse() מאפשרת לראות את המכסה שנוצלה על ידי StorageArea.

getKeys()

ה-method‏ getKeys() מאפשרת לקבל את כל המפתחות שמאוחסנים ב-StorageArea.

remove()‎

השיטה remove() מאפשרת להסיר פריט מ-StorageArea.

set()‎

השיטה set() מאפשרת להגדיר פריט ב-StorageArea.

setAccessLevel()

ה-method‏ setAccessLevel() מאפשרת לכם לשלוט בגישה אל StorageArea.

clear()‎

השיטה clear() מאפשרת למחוק את כל הנתונים מ-StorageArea.

onChanged

האירוע onChanged מאפשר לכם לעקוב אחרי שינויים ב-StorageArea.

תרחישים לדוגמה

בקטעים הבאים מפורטים תרחישים נפוצים לשימוש ב-Storage API.

מה עושים כשמקבלים עדכונים לגבי נפח האחסון

כדי לעקוב אחרי שינויים שבוצעו באחסון, מוסיפים פונקציית listener לאירוע onChanged שלו. כשמשהו משתנה באחסון, האירוע הזה מופעל. הקוד לדוגמה מאזין לשינויים הבאים:

background.js:

browser.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;
  browser.storage.sync.set({ options });
});

// Initialize the form with the user's option settings
const data = await browser.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
browser.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 צריכים לפעמים לטעון נתונים מהאחסון באופן אסינכרוני לפני שהם מפעילים את הגורמים המטפלים באירועים. כדי לעשות את זה, קטע הקוד הבא משתמש בגורם מטפל אסינכרוני באירועים של 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 = browser.storage.sync.get().then((items) => {
  // Copy the data retrieved from storage into storageCache.
  Object.assign(storageCache, items);
});

browser.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;
  browser.storage.sync.set(storageCache);
});

כלי פיתוח

אתם יכולים לראות ולערוך נתונים שמאוחסנים באמצעות ה-API בכלי הפיתוח. מידע נוסף זמין בדף הצגה ועריכה של אחסון התוספים במסמכי התיעוד של כלי הפיתוח.

סוגים

AccessLevel

‫Chrome 102 ואילך ‫‎browser.* ‎ מגרסת Chrome 148

רמת הגישה של אזור האחסון.

טיפוסים בני מנייה (enum)

"TRUSTED_CONTEXTS"
מציין הקשרים שמקורם בתוסף עצמו.

"TRUSTED_AND_UNTRUSTED_CONTEXTS"
מציין הקשרים שמקורם מחוץ לתוסף.

StorageChange

מאפיינים

  • newValue

    any optional

    הערך החדש של הפריט, אם יש ערך חדש.

  • oldValue

    any optional

    הערך הישן של הפריט, אם היה ערך ישן.

מאפיינים

local

הפריטים באזור האחסון local הם מקומיים לכל מכונה.

סוג

StorageArea ואובייקט

מאפיינים

  • QUOTA_BYTES

    10485760

    כמות הנתונים המקסימלית (בבייטים) שאפשר לאחסן באחסון המקומי, כפי שנמדדת על ידי מחרוזת JSON של כל ערך בתוספת האורך של כל מפתח. המערכת תתעלם מהערך הזה אם לתוסף יש את ההרשאה unlimitedStorage. עדכונים שגורמים לחריגה מהמגבלה הזו נכשלים מיד ומגדירים את runtime.lastError כשמשתמשים בקריאה חוזרת (callback), או Promise שנדחה אם משתמשים ב-async/await.

managed

הפריטים באזור האחסון managed מוגדרים על ידי מדיניות ארגונית שנקבעה על ידי מנהל הדומיין, והם לקריאה בלבד עבור התוסף. ניסיון לשנות את מרחב השמות הזה יגרום לשגיאה. מידע על הגדרת מדיניות זמין במאמר מניפסט לאזורי אחסון.

סוג

session

Chrome 102 ואילך browser.* ‎ מ-Chrome 148 MV3 ואילך

הפריטים באזור האחסון 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

    הוצא משימוש

    ל-API‏ storage.sync אין יותר מכסה לפעולות כתיבה מתמשכות.

  • 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

    102,400

    הכמות הכוללת המקסימלית (בבייטים) של נתונים שאפשר לאחסן באחסון הסנכרון, כפי שנמדדת על ידי מחרוזת JSON של כל ערך בתוספת האורך של כל מפתח. עדכונים שגורמים לחריגה מהמגבלה הזו נכשלים באופן מיידי ומגדירים את runtime.lastError כשמשתמשים בקריאה חוזרת (callback), או כש-Promise נדחה.

  • QUOTA_BYTES_PER_ITEM

    8192

    הגודל המקסימלי (בבייטים) של כל פריט בנפרד באחסון הסנכרון, כפי שנמדד על ידי מחרוזת ה-JSON של הערך שלו בתוספת אורך המפתח שלו. עדכונים שמכילים פריטים שגדולים מהמגבלה הזו ייכשלו מיד ויוגדר runtime.lastError כשמשתמשים בקריאה חוזרת (callback), או כש-Promise נדחה.

אירועים

onChanged

browser.storage.onChanged.addListener(
  callback: function,
)

מופעל כשפריט אחד או יותר משתנה.

פרמטרים

  • callback

    פונקציה

    הפרמטר callback נראה כך:

    (changes: object, areaName: string) => void

    • שינויים

      אובייקט

    • areaName

      מחרוזת