chrome.storage

תיאור

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

הרשאות

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. בודקים את chrome.storage ב-service worker של התוסף כדי לראות את הנתונים שלכם.
  4. אם הנתונים לא נמצאים, [יוצרים][create-offscreen] מסמך מחוץ למסך וקוראים ל-‎[sendMessage()][send-message] כדי להתחיל את תהליך ההמרה.
  5. בתוך ה-handler‏ onMessage של המסמך מחוץ למסך, קוראים לשגרה של ההמרה.

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

אזורי אחסון

‫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
אדמינים יכולים להשתמש בסכימה ובמדיניות Chrome Enterprise כדי להגדיר את ההגדרות של תוסף תומך בסביבה מנוהלת. אזור האחסון הזה הוא לקריאה בלבד.

מניפסט

כדי להשתמש ב-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);
  }
});

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

מכיוון ש-service workers לא תמיד פועלים, לפעמים תוספי 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);
});

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

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

סוגים

AccessLevel

Chrome 102 ואילך

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

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 ואילך

      ההבטחות נתמכות רק ב-Manifest V3 ובגרסאות מאוחרות יותר. בפלטפורמות אחרות צריך להשתמש בפונקציות Callback.

  • get

    void

    Promise

    מקבל פריט אחד או יותר מהאחסון.

    הפונקציה get נראית כך:

    (keys?: string | string[] | object, callback?: function) => {...}

    • מפתחות

      מחרוזת | מערך מחרוזות | אובייקט אופציונלי

      מפתח יחיד להשגה, רשימת מפתחות להשגה או מילון שמציין ערכי ברירת מחדל (ראו תיאור של האובייקט). רשימה או אובייקט ריקים יחזירו אובייקט תוצאה ריק. מעבירים את null כדי לקבל את כל התוכן של האחסון.

    • callback

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

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

      (items: object) => void

      • פריטים

        אובייקט

        אובייקט עם פריטים במיפויי מפתח-ערך.

    • החזרות

      Promise<object>

      Chrome 95 ואילך

      ההבטחות נתמכות רק ב-Manifest V3 ובגרסאות מאוחרות יותר. בפלטפורמות אחרות צריך להשתמש בפונקציות Callback.

  • getBytesInUse

    void

    Promise

    הפונקציה מחזירה את כמות הנפח (בבייטים) שמשמשת פריט אחד או יותר.

    הפונקציה getBytesInUse נראית כך:

    (keys?: string | string[], callback?: function) => {...}

    • מפתחות

      מחרוזת | מערך מחרוזות אופציונלי

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

    • callback

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

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

      (bytesInUse: number) => void

      • bytesInUse

        number

        כמות המקום שנעשה בו שימוש באחסון, בבייטים.

    • החזרות

      Promise<number>

      Chrome 95 ואילך

      ההבטחות נתמכות רק ב-Manifest V3 ובגרסאות מאוחרות יותר. בפלטפורמות אחרות צריך להשתמש בפונקציות Callback.

  • getKeys

    void

    Promise Chrome 130+

    אחזור כל המפתחות מהאחסון.

    הפונקציה getKeys נראית כך:

    (callback?: function) => {...}

    • callback

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

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

      (keys: string[]) => void

      • מפתחות

        string[]

        מערך עם מפתחות שנקראו מהאחסון.

    • החזרות

      Promise<string[]>

      ההבטחות נתמכות רק ב-Manifest V3 ובגרסאות מאוחרות יותר. בפלטפורמות אחרות צריך להשתמש בפונקציות Callback.

  • remove

    void

    Promise

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

    הפונקציה remove נראית כך:

    (keys: string | string[], callback?: function) => {...}

    • מפתחות

      מחרוזת | מחרוזת[]

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

    • callback

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

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

      () => void

    • החזרות

      Promise<void>

      Chrome 95 ואילך

      ההבטחות נתמכות רק ב-Manifest V3 ובגרסאות מאוחרות יותר. בפלטפורמות אחרות צריך להשתמש בפונקציות Callback.

  • הוגדר

    void

    Promise

    הגדרת כמה פריטים.

    הפונקציה set נראית כך:

    (items: object, callback?: function) => {...}

    • פריטים

      אובייקט

      אובייקט שכולל כל צמד מפתח/ערך לעדכון האחסון. צמדי מפתח/ערך אחרים באחסון לא יושפעו.

      ערכים פרימיטיביים כמו מספרים יעברו סריאליזציה כמצופה. ערכים עם typeof "object" ו-"function" בדרך כלל יעברו סריאליזציה ל-{}, למעט Array (עובר סריאליזציה כצפוי), Date ו-Regex (עוברים סריאליזציה באמצעות הייצוג שלהם ב-String).

    • callback

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

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

      () => void

    • החזרות

      Promise<void>

      Chrome 95 ואילך

      ההבטחות נתמכות רק ב-Manifest V3 ובגרסאות מאוחרות יותר. בפלטפורמות אחרות צריך להשתמש בפונקציות Callback.

  • setAccessLevel

    void

    Promise Chrome 102+

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

    הפונקציה setAccessLevel נראית כך:

    (accessOptions: object, callback?: function) => {...}

    • accessOptions

      אובייקט

      • accessLevel

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

    • callback

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

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

      () => void

    • החזרות

      Promise<void>

      ההבטחות נתמכות רק ב-Manifest V3 ובגרסאות מאוחרות יותר. בפלטפורמות אחרות צריך להשתמש בפונקציות Callback.

StorageChange

מאפיינים

  • newValue

    כל מאפיין אופציונלי

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

  • oldValue

    כל מאפיין אופציונלי

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

מאפיינים

local

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

סוג

StorageArea ו-object

מאפיינים

  • QUOTA_BYTES

    10485760

    הכמות המקסימלית (בבייטים) של נתונים שאפשר לאחסן באחסון מקומי, כפי שנמדדת על ידי המרת כל ערך למחרוזת JSON בתוספת האורך של כל מפתח. המערכת תתעלם מהערך הזה אם לתוסף יש הרשאה מסוג unlimitedStorage. עדכונים שיגרמו לחריגה מהמגבלה הזו ייכשלו באופן מיידי ויגדירו את runtime.lastError אם משתמשים בפונקציית קריאה חוזרת, או 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 כשמשתמשים בפונקציית קריאה חוזרת, או כשמתבצעת דחייה של 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

      מחרוזת