chrome.storage

Mô tả

Sử dụng API chrome.storage để lưu trữ, truy xuất và theo dõi các thay đổi đối với dữ liệu người dùng.

Quyền

storage

Để sử dụng Storage API, hãy khai báo quyền "storage" trong tệp kê khai của tiện ích. Ví dụ:

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

Khái niệm và cách sử dụng

Storage API cung cấp một cách thức dành riêng cho tiện ích để duy trì dữ liệu và trạng thái người dùng. API này tương tự như các API lưu trữ của nền tảng web (IndexedDBStorage), nhưng được thiết kế để đáp ứng nhu cầu lưu trữ của các tiện ích. Sau đây là một số tính năng chính:

  • Tất cả các ngữ cảnh tiện ích, bao gồm cả trình thực thi dịch vụ tiện ích và tập lệnh nội dung đều có quyền truy cập vào Storage API.
  • Các giá trị có thể chuyển đổi tuần tự JSON được lưu trữ dưới dạng thuộc tính đối tượng.
  • Storage API là không đồng bộ với các thao tác đọc và ghi hàng loạt.
  • Ngay cả khi người dùng xoá bộ nhớ đệm và nhật ký duyệt web, dữ liệu vẫn được lưu giữ.
  • Các chế độ cài đặt đã lưu vẫn được giữ nguyên ngay cả khi bạn dùng chế độ ẩn danh chia đôi.
  • Bao gồm một vùng lưu trữ được quản lý chỉ đọc dành riêng cho các chính sách của doanh nghiệp.

Tiện ích có thể sử dụng các API bộ nhớ trên web không?

Mặc dù các tiện ích có thể sử dụng giao diện Storage (có thể truy cập từ window.localStorage) trong một số ngữ cảnh (cửa sổ bật lên và các trang HTML khác), nhưng chúng tôi không khuyến khích bạn sử dụng giao diện này vì những lý do sau:

  • Trình chạy dịch vụ của tiện ích không thể sử dụng Web Storage API.
  • Tập lệnh nội dung chia sẻ bộ nhớ với trang lưu trữ.
  • Dữ liệu được lưu bằng Web Storage API sẽ bị mất khi người dùng xoá nhật ký duyệt web.

Cách di chuyển dữ liệu từ API bộ nhớ web sang API bộ nhớ tiện ích từ một worker dịch vụ:

  1. Chuẩn bị một trang HTML tài liệu ngoài màn hình và tệp kịch bản. Tệp tập lệnh phải chứa một quy trình chuyển đổi và một trình xử lý onMessage.
  2. Trong worker dịch vụ của tiện ích, hãy kiểm tra chrome.storage để biết dữ liệu của bạn.
  3. Nếu không tìm thấy dữ liệu của bạn, hãy gọi createDocument().
  4. Sau khi Promise được trả về phân giải, hãy gọi sendMessage() để bắt đầu quy trình chuyển đổi.
  5. Trong trình xử lý onMessage của tài liệu ngoài màn hình, hãy gọi quy trình chuyển đổi.

Ngoài ra, còn có một số điểm khác biệt về cách hoạt động của các API bộ nhớ trên web trong tiện ích. Tìm hiểu thêm trong bài viết Bộ nhớ và cookie.

Khu vực lưu trữ

Storage API được chia thành các vùng lưu trữ sau:

storage.local
Dữ liệu được lưu trữ cục bộ và sẽ bị xoá khi bạn xoá tiện ích. Giới hạn bộ nhớ là 10 MB (5 MB trong Chrome 113 trở xuống), nhưng bạn có thể tăng giới hạn này bằng cách yêu cầu quyền "unlimitedStorage". Bạn nên dùng storage.local để lưu trữ lượng dữ liệu lớn hơn. Theo mặc định, API này được cung cấp cho tập lệnh nội dung, nhưng bạn có thể thay đổi hành vi này bằng cách gọi chrome.storage.local.setAccessLevel().
storage.managed
Bộ nhớ được quản lý là bộ nhớ chỉ đọc dành cho các tiện ích được cài đặt theo chính sách và do quản trị viên hệ thống quản lý bằng cách sử dụng giản đồ do nhà phát triển xác định và các chính sách của doanh nghiệp. Các chính sách tương tự như các lựa chọn nhưng do quản trị viên hệ thống định cấu hình thay vì người dùng, cho phép tiện ích được định cấu hình sẵn cho tất cả người dùng của một tổ chức. Để biết thông tin về các chính sách, hãy xem Tài liệu dành cho quản trị viên. Để tìm hiểu thêm về vùng lưu trữ managed, hãy xem phần Tệp kê khai cho các vùng lưu trữ.
storage.session
Lưu giữ dữ liệu trong bộ nhớ trong khi một tiện ích được tải. Bộ nhớ sẽ bị xoá nếu tiện ích bị vô hiệu hoá, tải lại hoặc cập nhật và khi trình duyệt khởi động lại. Theo mặc định, API này không được hiển thị cho các tập lệnh nội dung, nhưng bạn có thể thay đổi hành vi này bằng cách gọi chrome.storage.session.setAccessLevel(). Giới hạn bộ nhớ là 10 MB (1 MB trong Chrome 111 trở xuống). Giao diện storage.session là một trong số những giao diện mà chúng tôi đề xuất cho các worker dịch vụ.
storage.sync
Nếu tính năng đồng bộ hoá được bật, dữ liệu sẽ được đồng bộ hoá với mọi trình duyệt Chrome mà người dùng đã đăng nhập. Nếu bị vô hiệu hoá, nó sẽ hoạt động như storage.local. Chrome lưu trữ dữ liệu cục bộ khi trình duyệt không có kết nối mạng và tiếp tục đồng bộ hoá khi có kết nối mạng trở lại. Hạn mức là khoảng 100 KB, 8 KB cho mỗi mục. Bạn nên sử dụng storage.sync để giữ nguyên chế độ cài đặt của người dùng trên các trình duyệt đã đồng bộ hoá. Nếu bạn đang làm việc với dữ liệu nhạy cảm của người dùng, hãy sử dụng storage.session. Theo mặc định, storage.sync sẽ được hiển thị cho tập lệnh nội dung, nhưng bạn có thể thay đổi hành vi này bằng cách gọi chrome.storage.sync.setAccessLevel().

Hạn mức bộ nhớ và hạn mức điều tiết

Storage API có những hạn chế sau đây về việc sử dụng:

  • Việc lưu trữ dữ liệu thường đi kèm với chi phí hiệu suất và API này có hạn mức lưu trữ. Bạn nên thận trọng về dữ liệu mà bạn lưu trữ để không mất khả năng lưu trữ dữ liệu.
  • Quá trình lưu trữ có thể mất một chút thời gian để hoàn tất. Đảm bảo bạn cấu trúc mã để tính đến thời gian đó.

Để biết thông tin chi tiết về các hạn chế đối với dung lượng lưu trữ và những việc sẽ xảy ra khi bạn vượt quá hạn mức, hãy xem thông tin hạn mức của sync, localsession.

Trường hợp sử dụng

Các phần sau đây minh hoạ các trường hợp sử dụng phổ biến cho Storage API.

Phản hồi thông tin cập nhật về bộ nhớ

Để theo dõi các thay đổi đối với bộ nhớ, hãy thêm một trình nghe vào sự kiện onChanged của bộ nhớ. Khi có bất kỳ thay đổi nào về bộ nhớ, sự kiện đó sẽ kích hoạt. Mã mẫu sẽ theo dõi những thay đổi này:

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}".`
    );
  }
});

Chúng ta có thể phát triển ý tưởng này hơn nữa. Trong ví dụ này, chúng ta có một trang tuỳ chọn cho phép người dùng bật/tắt "chế độ gỡ lỗi" (không minh hoạ cách triển khai ở đây). Trang tuỳ chọn sẽ lưu ngay các chế độ cài đặt mới vào storage.sync và trình chạy dịch vụ sẽ dùng storage.onChanged để áp dụng chế độ cài đặt này trong thời gian sớm nhất có thể.

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);
  }
});

Tải trước không đồng bộ từ bộ nhớ

Vì các worker dịch vụ không chạy liên tục, nên đôi khi các tiện ích Manifest V3 cần tải dữ liệu không đồng bộ từ bộ nhớ trước khi thực thi trình xử lý sự kiện. Để thực hiện việc này, đoạn mã sau đây sẽ dùng một trình xử lý sự kiện action.onClicked không đồng bộ, chờ storageCache toàn cục được điền sẵn trước khi thực thi logic của nó.

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);
});

Công cụ cho nhà phát triển

Bạn có thể xem và chỉnh sửa dữ liệu được lưu trữ bằng API trong Công cụ cho nhà phát triển. Để tìm hiểu thêm, hãy xem trang Xem và chỉnh sửa bộ nhớ của tiện ích trong tài liệu về Công cụ cho nhà phát triển.

Ví dụ

Các mẫu sau đây minh hoạ các vùng lưu trữ local, syncsession:

Địa phương

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);
});

Đồng bộ hoá

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);
});

Phiên

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);
});

Để xem các bản minh hoạ khác về Storage API, hãy khám phá bất kỳ mẫu nào sau đây:

Loại

AccessLevel

Chrome 102 trở lên

Cấp truy cập của vùng lưu trữ.

Enum

"TRUSTED_CONTEXTS"
Chỉ định các bối cảnh bắt nguồn từ chính tiện ích.

"TRUSTED_AND_UNTRUSTED_CONTEXTS"
Chỉ định các bối cảnh bắt nguồn từ bên ngoài tiện ích.

StorageArea

Thuộc tính

  • onChanged

    Event<functionvoidvoid>

    Chrome 73 trở lên

    Kích hoạt khi một hoặc nhiều mục thay đổi.

    Hàm onChanged.addListener có dạng như sau:

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

    • callback

      hàm

      Tham số callback có dạng như sau:

      (changes: object) => void

      • các thay đổi

        đối tượng

  • xóa

    void

    Promise

    Xoá tất cả các mục khỏi bộ nhớ.

    Hàm clear có dạng như sau:

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

    • callback

      hàm không bắt buộc

      Tham số callback có dạng như sau:

      () => void

    • returns

      Promise<void>

      Chrome 95 trở lên

      Promise được hỗ trợ trong Manifest V3 trở lên, nhưng lệnh gọi lại được cung cấp để đảm bảo khả năng tương thích ngược. Bạn không thể sử dụng cả hai trên cùng một lệnh gọi hàm. Lời hứa này sẽ phân giải bằng cùng một loại được truyền đến lệnh gọi lại.

  • get

    void

    Promise

    Lấy một hoặc nhiều mục từ bộ nhớ.

    Hàm get có dạng như sau:

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

    • khoá

      string | string[] | object không bắt buộc

      Một khoá duy nhất để nhận, danh sách khoá để nhận hoặc một từ điển chỉ định các giá trị mặc định (xem phần mô tả về đối tượng). Một danh sách hoặc đối tượng trống sẽ trả về một đối tượng kết quả trống. Truyền null để nhận toàn bộ nội dung của bộ nhớ.

    • callback

      hàm không bắt buộc

      Tham số callback có dạng như sau:

      (items: object) => void

      • mục

        đối tượng

        Đối tượng có các mục trong mối liên kết khoá-giá trị.

    • returns

      Promise<object>

      Chrome 95 trở lên

      Promise được hỗ trợ trong Manifest V3 trở lên, nhưng lệnh gọi lại được cung cấp để đảm bảo khả năng tương thích ngược. Bạn không thể sử dụng cả hai trên cùng một lệnh gọi hàm. Lời hứa này sẽ phân giải bằng cùng một loại được truyền đến lệnh gọi lại.

  • getBytesInUse

    void

    Promise

    Lấy lượng không gian (tính bằng byte) mà một hoặc nhiều mục đang sử dụng.

    Hàm getBytesInUse có dạng như sau:

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

    • khoá

      string | string[] không bắt buộc

      Một khoá hoặc danh sách khoá để nhận tổng mức sử dụng. Một danh sách trống sẽ trả về 0. Truyền null để biết tổng mức sử dụng của tất cả bộ nhớ.

    • callback

      hàm không bắt buộc

      Tham số callback có dạng như sau:

      (bytesInUse: number) => void

      • bytesInUse

        số

        Dung lượng bộ nhớ đang dùng, tính bằng byte.

    • returns

      Promise<number>

      Chrome 95 trở lên

      Promise được hỗ trợ trong Manifest V3 trở lên, nhưng lệnh gọi lại được cung cấp để đảm bảo khả năng tương thích ngược. Bạn không thể sử dụng cả hai trên cùng một lệnh gọi hàm. Lời hứa này sẽ phân giải bằng cùng một loại được truyền đến lệnh gọi lại.

  • getKeys

    void

    Promise Chrome 130 trở lên

    Lấy tất cả các khoá từ bộ nhớ.

    Hàm getKeys có dạng như sau:

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

    • callback

      hàm không bắt buộc

      Tham số callback có dạng như sau:

      (keys: string[]) => void

      • khoá

        string[]

        Mảng có các khoá được đọc từ bộ nhớ.

    • returns

      Promise<string[]>

      Promise được hỗ trợ trong Manifest V3 trở lên, nhưng lệnh gọi lại được cung cấp để đảm bảo khả năng tương thích ngược. Bạn không thể sử dụng cả hai trên cùng một lệnh gọi hàm. Lời hứa này sẽ phân giải bằng cùng một loại được truyền đến lệnh gọi lại.

  • xoá

    void

    Promise

    Xoá một hoặc nhiều mục khỏi bộ nhớ.

    Hàm remove có dạng như sau:

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

    • khoá

      chuỗi | string[]

      Một khoá duy nhất hoặc danh sách khoá cho các mục cần xoá.

    • callback

      hàm không bắt buộc

      Tham số callback có dạng như sau:

      () => void

    • returns

      Promise<void>

      Chrome 95 trở lên

      Promise được hỗ trợ trong Manifest V3 trở lên, nhưng lệnh gọi lại được cung cấp để đảm bảo khả năng tương thích ngược. Bạn không thể sử dụng cả hai trên cùng một lệnh gọi hàm. Lời hứa này sẽ phân giải bằng cùng một loại được truyền đến lệnh gọi lại.

  • đặt

    void

    Promise

    Đặt nhiều mục.

    Hàm set có dạng như sau:

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

    • mục

      đối tượng

      Một đối tượng cung cấp từng cặp khoá/giá trị để cập nhật bộ nhớ. Mọi cặp khoá/giá trị khác trong bộ nhớ sẽ không bị ảnh hưởng.

      Các giá trị gốc, chẳng hạn như số, sẽ được chuyển đổi tuần tự như dự kiến. Các giá trị có typeof "object""function" thường sẽ chuyển đổi tuần tự thành {}, ngoại trừ Array (chuyển đổi tuần tự như dự kiến), DateRegex (chuyển đổi tuần tự bằng cách sử dụng biểu thị String).

    • callback

      hàm không bắt buộc

      Tham số callback có dạng như sau:

      () => void

    • returns

      Promise<void>

      Chrome 95 trở lên

      Promise được hỗ trợ trong Manifest V3 trở lên, nhưng lệnh gọi lại được cung cấp để đảm bảo khả năng tương thích ngược. Bạn không thể sử dụng cả hai trên cùng một lệnh gọi hàm. Lời hứa này sẽ phân giải bằng cùng một loại được truyền đến lệnh gọi lại.

  • setAccessLevel

    void

    Promise Chrome 102 trở lên

    Đặt cấp truy cập mong muốn cho vùng lưu trữ. Theo mặc định, bộ nhớ session chỉ được phép truy cập trong các bối cảnh đáng tin cậy (trang tiện ích và trình chạy dịch vụ), trong khi bộ nhớ localsync cho phép truy cập từ cả bối cảnh đáng tin cậy và không đáng tin cậy.

    Hàm setAccessLevel có dạng như sau:

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

    • accessOptions

      đối tượng

      • accessLevel

        Cấp truy cập của vùng lưu trữ.

    • callback

      hàm không bắt buộc

      Tham số callback có dạng như sau:

      () => void

    • returns

      Promise<void>

      Promise được hỗ trợ trong Manifest V3 trở lên, nhưng lệnh gọi lại được cung cấp để đảm bảo khả năng tương thích ngược. Bạn không thể sử dụng cả hai trên cùng một lệnh gọi hàm. Lời hứa này sẽ phân giải bằng cùng một loại được truyền đến lệnh gọi lại.

StorageChange

Thuộc tính

  • newValue

    bất kỳ không bắt buộc

    Giá trị mới của mặt hàng (nếu có).

  • oldValue

    bất kỳ không bắt buộc

    Giá trị cũ của mặt hàng (nếu có).

Thuộc tính

local

Các mục trong vùng lưu trữ local là cục bộ đối với từng máy.

Loại

StorageArea và đối tượng

Thuộc tính

  • QUOTA_BYTES

    10485760

    Lượng dữ liệu tối đa (tính bằng byte) có thể được lưu trữ trong bộ nhớ cục bộ, được đo bằng cách chuyển đổi chuỗi JSON của mọi giá trị cộng với độ dài của mọi khoá. Giá trị này sẽ bị bỏ qua nếu tiện ích có quyền unlimitedStorage. Các bản cập nhật vượt quá giới hạn này sẽ thất bại ngay lập tức và đặt runtime.lastError khi sử dụng lệnh gọi lại hoặc một Lời hứa bị từ chối nếu sử dụng async/await.

managed

Các mục trong vùng lưu trữ managed được đặt theo chính sách doanh nghiệp do quản trị viên miền định cấu hình và chỉ có thể đọc đối với tiện ích; việc cố gắng sửa đổi không gian tên này sẽ dẫn đến lỗi. Để biết thông tin về cách định cấu hình chính sách, hãy xem phần Tệp kê khai cho các vùng lưu trữ.

Loại

session

Chrome 102 trở lên MV3 trở lên

Các mục trong vùng lưu trữ session được lưu trữ trong bộ nhớ và sẽ không được duy trì trên ổ đĩa.

Loại

StorageArea và đối tượng

Thuộc tính

  • QUOTA_BYTES

    10485760

    Lượng dữ liệu tối đa (tính bằng byte) có thể được lưu trữ trong bộ nhớ, được đo bằng cách ước tính mức sử dụng bộ nhớ được phân bổ động của mọi giá trị và khoá. Những bản cập nhật khiến giới hạn này bị vượt quá sẽ thất bại ngay lập tức và đặt runtime.lastError khi sử dụng một lệnh gọi lại hoặc khi một Lời hứa bị từ chối.

sync

Các mục trong vùng lưu trữ sync được đồng bộ hoá bằng Chrome Sync.

Loại

StorageArea và đối tượng

Thuộc tính

  • MAX_ITEMS

    512

    Số lượng mục tối đa có thể được lưu trữ trong bộ nhớ đồng bộ hoá. Những bản cập nhật khiến hạn mức này bị vượt quá sẽ thất bại ngay lập tức và đặt runtime.lastError khi sử dụng một lệnh gọi lại hoặc khi một Lời hứa bị từ chối.

  • MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE

    1000000

    Không dùng nữa

    API storage.sync không còn hạn mức hoạt động ghi liên tục nữa.

  • MAX_WRITE_OPERATIONS_PER_HOUR

    1800

    Số lượng tối đa các thao tác set, remove hoặc clear có thể được thực hiện mỗi giờ. Đây là 1 lần ghi sau mỗi 2 giây, thấp hơn giới hạn ghi mỗi phút cao hơn trong thời gian ngắn.

    Những bản cập nhật khiến giới hạn này bị vượt quá sẽ thất bại ngay lập tức và đặt runtime.lastError khi sử dụng một lệnh gọi lại hoặc khi một Lời hứa bị từ chối.

  • MAX_WRITE_OPERATIONS_PER_MINUTE

    120

    Số lượng tối đa các thao tác set, remove hoặc clear có thể thực hiện mỗi phút. Đây là 2 lượt ghi mỗi giây, mang lại thông lượng cao hơn so với số lượt ghi mỗi giờ trong khoảng thời gian ngắn hơn.

    Những bản cập nhật khiến giới hạn này bị vượt quá sẽ thất bại ngay lập tức và đặt runtime.lastError khi sử dụng một lệnh gọi lại hoặc khi một Lời hứa bị từ chối.

  • QUOTA_BYTES

    102400

    Tổng lượng dữ liệu tối đa (tính bằng byte) có thể được lưu trữ trong bộ nhớ đồng bộ hoá, được đo bằng cách chuyển đổi chuỗi JSON của mọi giá trị cộng với độ dài của mọi khoá. Những bản cập nhật khiến giới hạn này bị vượt quá sẽ thất bại ngay lập tức và đặt runtime.lastError khi sử dụng một lệnh gọi lại hoặc khi một Lời hứa bị từ chối.

  • QUOTA_BYTES_PER_ITEM

    8192

    Kích thước tối đa (tính bằng byte) của từng mục riêng lẻ trong bộ nhớ đồng bộ hoá, được đo bằng cách chuyển đổi chuỗi JSON của giá trị cộng với độ dài khoá của mục đó. Những bản cập nhật chứa các mục lớn hơn giới hạn này sẽ thất bại ngay lập tức và đặt runtime.lastError khi sử dụng một lệnh gọi lại hoặc khi một Lời hứa bị từ chối.

Sự kiện

onChanged

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

Kích hoạt khi một hoặc nhiều mục thay đổi.

Thông số

  • callback

    hàm

    Tham số callback có dạng như sau:

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

    • các thay đổi

      đối tượng

    • areaName

      chuỗi