chrome.storage

תיאור

אפשר להשתמש ב-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:

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

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

אזורי אחסון

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

storage.local
הנתונים נשמרים באופן מקומי ומנקים כשהתוסף מוסר. מגבלת האחסון היא 10MB (5MB ב-Chrome 113 ובגרסאות קודמות), אבל אפשר להגדיל אותה באמצעות בקשת ההרשאה "unlimitedStorage". כדי לאחסן כמויות גדולות יותר של נתונים, מומלץ להשתמש בכלי storage.local.
storage.managed
אחסון מנוהל הוא אחסון לקריאה בלבד לתוספי מדיניות שהותקנו, ומנוהל על ידי אדמינים של המערכת באמצעות סכימה שהוגדרו על ידי המפתח ומדיניות ארגונית. כללי המדיניות דומים לאפשרויות, אבל מוגדרים על ידי מנהל מערכת במקום המשתמש. כתוצאה מכך, התוסף יכול להיות מוגדר מראש לכל המשתמשים בארגון. מידע על המדיניות זמין במסמכים לאדמינים. מידע נוסף על נפח האחסון ב-managed זמין במניפסט לאזורי האחסון.
storage.session
שמירת הנתונים בזיכרון במהלך סשן בדפדפן. כברירת מחדל, ה-API לא חשוף לסקריפטים של תוכן, אבל אפשר לשנות את ההתנהגות הזו על ידי הגדרה של chrome.storage.session.setAccessLevel(). מגבלת האחסון היא 10MB (1 MB ב-Chrome 111 ובגרסאות קודמות). הממשק של storage.session הוא אחד מתוך כמה פתרונות שאנחנו ממליצים עליהם ל-Service Workers.
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);
  }
});

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

מכיוון ש-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);
});

דוגמאות

בדוגמאות הבאות אפשר לראות את אזורי האחסון 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

Chrome 102 ומעלה

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

טיפוסים בני מנייה (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[]|object optional

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

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

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

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

      (items: object)=>void

      • items

        אובייקט

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

    • החזרות

      Promise<object>

      Chrome 88 ומעלה

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

  • getBytesInUse

    void

    הבטחה

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

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

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

    • מפתחות

      string|string[] optional

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

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

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

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

      (bytesInUse: number)=>void

      • bytesInUse

        number

        נפח האחסון שנוצל באחסון, בבייטים.

    • החזרות

      הבטחה<number>

      Chrome 88 ומעלה

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

  • remove

    void

    הבטחה

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

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

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

    • מפתחות

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

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

    • קריאה חוזרת (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

Chrome 102+ 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

    הוצא משימוש

    ל-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

      מחרוזת