chrome.storage

תיאור

שימוש ב-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:

  1. יוצרים מסמך מחוץ למסך עם תוכנית המרה וטיפול באירוע [onMessage][on-message].
  2. הוספת תהליך המרה למסמך מחוץ למסך.
  3. ב-service worker של התוסף, בודקים את chrome.storage כדי למצוא את הנתונים.
  4. אם הנתונים לא נמצאים, [יוצרים][create-offscreen] מסמך מחוץ למסך ומפעילים את [sendMessage()][send-message] כדי להתחיל את תהליך ההמרה.
  5. בתוך הטיפול onMessage של המסמך מחוץ למסך, קוראים לתוכנית ההמרה.

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

אזורי אחסון

Storage API מחולק לארבעה קטגוריות ('אזורי אחסון'):

storage.local
הנתונים מאוחסנים באופן מקומי ונמחקים כשהתוסף מוסר. מגבלת המכסה היא כ-10MB, אבל אפשר להגדיל אותה על ידי בקשה להרשאה "unlimitedStorage". כדאי להשתמש בהם כדי לאחסן כמויות גדולות יותר של נתונים.
storage.sync
אם הסנכרון מופעל, הנתונים מסתנכרנים עם כל דפדפן Chrome שאליו המשתמש מחובר. אם המדיניות מושבתת, היא פועלת כמו storage.local. Chrome שומר את הנתונים באופן מקומי כשהדפדפן במצב אופליין, וממשיך את הסנכרון כשהדפדפן חוזר לאינטרנט. מגבלת המכסה היא כ-100KB, 8KB לכל פריט. מומלץ להשתמש בה כדי לשמור את הגדרות המשתמש בדפדפנים מסונכרנים.
storage.session
שמירת נתונים בזיכרון למשך סשן הדפדפן. כברירת מחדל, הוא לא חשוף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי הגדרת chrome.storage.session.setAccessLevel(). מגבלת המכסה היא כ-10MB. מומלץ להשתמש בו כדי לאחסן משתנים גלובליים במהלך ההרצות של ה-service worker.
storage.managed
אדמינים יכולים להשתמש בסכימה ובמדיניות הארגון כדי להגדיר את ההגדרות של תוסף תומך בסביבה מנוהלת. אזור האחסון הזה הוא לקריאה בלבד.

מניפסט

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

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

שימוש

בדוגמאות הבאות מוצגים אזורי האחסון 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);
  }
});

טעינה אסינכרונית מראש מהאחסון

מאחר ששירותי ה-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);
});

דוגמאות לתוספים

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

סוגים

AccessLevel

גרסה 102 ואילך של Chrome

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

טיפוסים בני מנייה (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.

  • 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.

  • 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.

  • 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) => {...}

    • מפתחות

      string | string[]

      מפתח יחיד או רשימת מפתחות לפריטים להסרה.

    • קריאה חוזרת (callback)

      פונקציה אופציונלי

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

      () => void

    • החזרות

      Promise<void>

      גרסה 88 ואילך של Chrome

      יש תמיכה ב-Promises רק ב-Manifest V3 ואילך. בפלטפורמות אחרות צריך להשתמש ב-callbacks.

  • הוגדר

    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.

  • setAccessLevel

    void

    Promise Chrome מגרסה 102 ואילך

    הגדרת רמת הגישה הרצויה לאזור האחסון. ברירת המחדל תהיה רק הקשרים המהימנים.

    הפונקציה 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 כשמשתמשים ב-callback, או Promise שנדחה אם משתמשים ב-async/await.

managed

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

סוג

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

      מחרוזת