คำอธิบาย
ใช้ chrome.storage API เพื่อจัดเก็บ ดึงข้อมูล และติดตามการเปลี่ยนแปลงข้อมูลผู้ใช้
สิทธิ์
storageหากต้องการใช้ Storage API ให้ประกาศสิทธิ์ "storage" ในไฟล์ Manifest ของส่วนขยาย เช่น
{
"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 มีวิธีเฉพาะสำหรับส่วนขยายในการคงข้อมูลและสถานะของผู้ใช้ไว้ ซึ่งคล้ายกับ Storage API ของแพลตฟอร์มเว็บ (IndexedDB และ Storage) แต่ได้รับการออกแบบมาเพื่อตอบสนองความต้องการด้านพื้นที่เก็บข้อมูลของส่วนขยาย ฟีเจอร์หลักบางส่วนมีดังนี้
- บริบทส่วนขยายทั้งหมด รวมถึง Service Worker ของส่วนขยายและสคริปต์เนื้อหาจะมีสิทธิ์เข้าถึง Storage API
- ระบบจะจัดเก็บค่าที่แปลงเป็น JSON ได้เป็นพร็อพเพอร์ตี้ออบเจ็กต์
- Storage API เป็นแบบอะซิงโครนัสที่มีการดำเนินการอ่านและเขียนแบบหลายรายการพร้อมกัน
- แม้ว่าผู้ใช้จะล้างแคชและประวัติการท่องเว็บ ข้อมูลก็จะยังคงอยู่
- การตั้งค่าที่จัดเก็บไว้จะยังคงอยู่แม้ว่าจะใช้โหมดไม่ระบุตัวตนแบบแยกก็ตาม
- รวมพื้นที่เก็บข้อมูลที่มีการจัดการแบบอ่านอย่างเดียวสำหรับนโยบายระดับองค์กรโดยเฉพาะ
ส่วนขยายใช้ API พื้นที่เก็บข้อมูลบนเว็บได้ไหม
แม้ว่าส่วนขยายจะใช้อินเทอร์เฟซ Storage (เข้าถึงได้จาก window.localStorage) ในบางบริบท (ป๊อปอัปและหน้า HTML อื่นๆ) ได้ แต่เราไม่แนะนำให้ใช้ด้วยเหตุผลต่อไปนี้
- Service Worker ของส่วนขยายใช้ Web Storage API ไม่ได้
- สคริปต์เนื้อหาจะแชร์พื้นที่เก็บข้อมูลกับหน้าโฮสต์
- ข้อมูลที่บันทึกโดยใช้ Web Storage API จะสูญหายเมื่อผู้ใช้ล้างประวัติการท่องเว็บ
วิธีย้ายข้อมูลจาก Web Storage API ไปยัง Extension Storage API จาก Service Worker
- เตรียมหน้า HTML และไฟล์สคริปต์ของเอกสารนอกหน้าจอ ไฟล์สคริปต์ควรมีรูทีนการแปลงและแฮนเดิล
onMessage - ใน Service Worker ของส่วนขยาย ให้ตรวจสอบ
browser.storageเพื่อหาข้อมูลของคุณ - หากไม่พบข้อมูลของคุณ โปรดโทรหา
createDocument() - หลังจากที่ Promise ที่แสดงผลได้รับการแก้ไขแล้ว ให้เรียกใช้
sendMessage()เพื่อเริ่มรูทีน Conversion - ภายในแฮนเดิล
onMessageของเอกสารนอกหน้าจอ ให้เรียกใช้รูทีนการแปลง
นอกจากนี้ยังมีรายละเอียดปลีกย่อยบางอย่างเกี่ยวกับวิธีการทำงานของ API พื้นที่เก็บข้อมูลบนเว็บในส่วนขยาย ดูข้อมูลเพิ่มเติมได้ในบทความพื้นที่เก็บข้อมูลและคุกกี้
ขีดจำกัดของพื้นที่เก็บข้อมูลและการควบคุมปริมาณ
Storage API มีขีดจำกัดการใช้งานดังนี้
- การจัดเก็บข้อมูลมีค่าใช้จ่ายด้านประสิทธิภาพ และ API มีโควต้าพื้นที่เก็บข้อมูล วางแผนข้อมูลที่ต้องการจัดเก็บเพื่อรักษาพื้นที่เก็บข้อมูล
- การจัดเก็บอาจใช้เวลาสักครู่จึงจะเสร็จสมบูรณ์ จัดโครงสร้างโค้ดเพื่อพิจารณาเวลาดังกล่าว
โปรดดูรายละเอียดเกี่ยวกับข้อจำกัดของพื้นที่เก็บข้อมูลและสิ่งที่จะเกิดขึ้นเมื่อใช้พื้นที่เก็บข้อมูลเกินขีดจำกัดได้ที่ข้อมูลโควต้าสำหรับ sync, local และ session
พื้นที่จัดเก็บ
Storage API แบ่งออกเป็นพื้นที่เก็บข้อมูลต่อไปนี้
ในพื้นที่
ระบบจะจัดเก็บข้อมูลไว้ในเครื่องและล้างข้อมูลเมื่อนำส่วนขยายออก ขีดจำกัดพื้นที่เก็บข้อมูลคือ 10 MB (5 MB ใน Chrome 113 และเวอร์ชันก่อนหน้า) แต่สามารถเพิ่มได้โดยขอสิทธิ์ "unlimitedStorage" เราขอแนะนำให้ใช้ storage.local เพื่อจัดเก็บข้อมูลจำนวนมาก โดยค่าเริ่มต้น ระบบจะแสดงสคริปต์เนื้อหา แต่คุณเปลี่ยนลักษณะการทำงานนี้ได้โดยเรียกใช้ browser.storage.local.setAccessLevel()
ที่จัดการ
พื้นที่เก็บข้อมูลที่มีการจัดการจะเป็นแบบอ่านอย่างเดียวสำหรับส่วนขยายที่ติดตั้งตามนโยบาย ซึ่งจัดการโดยผู้ดูแลระบบ โดยใช้สคีมาที่นักพัฒนาซอฟต์แวร์กำหนดและนโยบายองค์กร นโยบายจะคล้ายกับตัวเลือก แต่จะกำหนดค่าโดยผู้ดูแลระบบแทนผู้ใช้ ซึ่งจะช่วยให้กำหนดค่าส่วนขยายล่วงหน้าสำหรับผู้ใช้ทั้งหมดในองค์กรได้
โดยค่าเริ่มต้น storage.managed จะแสดงต่อสคริปต์เนื้อหา แต่ลักษณะการทำงานนี้สามารถเปลี่ยนแปลงได้โดยการเรียกใช้ browser.storage.managed.setAccessLevel() ดูข้อมูลเกี่ยวกับนโยบายได้ที่เอกสารประกอบสำหรับผู้ดูแลระบบ ดูข้อมูลเพิ่มเติมเกี่ยวกับพื้นที่เก็บข้อมูล managed ได้ที่ไฟล์ Manifest สำหรับพื้นที่เก็บข้อมูล
เซสชัน
พื้นที่เก็บข้อมูลเซสชันจะเก็บข้อมูลไว้ในหน่วยความจำขณะที่โหลดส่วนขยาย ระบบจะล้างพื้นที่เก็บข้อมูลหากปิดใช้ โหลดซ้ำ อัปเดตส่วนขยาย และเมื่อรีสตาร์ทเบราว์เซอร์ โดยค่าเริ่มต้น ระบบจะไม่แสดงสคริปต์เนื้อหา แต่คุณเปลี่ยนลักษณะการทำงานนี้ได้โดยเรียกใช้ browser.storage.session.setAccessLevel() ขีดจำกัดพื้นที่เก็บข้อมูลคือ 10 MB (1 MB ใน Chrome 111 และเวอร์ชันก่อนหน้า)
อินเทอร์เฟซ storage.session เป็นหนึ่งในหลายๆ อินเทอร์เฟซที่เราแนะนำสำหรับ Service Worker
ซิงค์
หากผู้ใช้เปิดใช้การซิงค์ ข้อมูลจะซิงค์กับเบราว์เซอร์ Chrome ทุกรายการที่ผู้ใช้เข้าสู่ระบบอยู่ หากปิดใช้ ระบบจะทำงานเหมือน storage.local Chrome จะจัดเก็บข้อมูลไว้ในเครื่องเมื่อเบราว์เซอร์ออฟไลน์ และจะกลับมาซิงค์อีกครั้งเมื่อกลับมาออนไลน์ ขีดจำกัดโควต้าอยู่ที่ประมาณ 100 KB โดยจำกัด 8 KB ต่อรายการ
เราขอแนะนำให้ใช้ storage.sync เพื่อคงการตั้งค่าของผู้ใช้ในเบราว์เซอร์ที่ซิงค์ไว้ หากคุณทำงานกับข้อมูลที่ละเอียดอ่อนของผู้ใช้ ให้ใช้ storage.session แทน โดยค่าเริ่มต้น storage.sync จะแสดงต่อสคริปต์เนื้อหา แต่ลักษณะการทำงานนี้สามารถเปลี่ยนแปลงได้โดยการเรียกใช้ browser.storage.sync.setAccessLevel()
เมธอดและเหตุการณ์
พื้นที่เก็บข้อมูลทั้งหมดใช้อินเทอร์เฟซ StorageArea
get()
เมธอด get() ช่วยให้คุณอ่านคีย์อย่างน้อย 1 รายการจาก StorageArea ได้
getBytesInUse()
เมธอด getBytesInUse() ช่วยให้คุณดูโควต้าที่ StorageArea ใช้ได้
getKeys()
เมธอด getKeys() ช่วยให้คุณได้รับคีย์ทั้งหมดที่จัดเก็บไว้ใน StorageArea
remove()
เมธอด remove() ช่วยให้คุณนำรายการออกจาก StorageArea ได้
set()
เมธอด set() ช่วยให้คุณตั้งค่ารายการใน StorageArea ได้
setAccessLevel()
เมธอด setAccessLevel() ช่วยให้คุณควบคุมการเข้าถึง StorageArea ได้
clear()
เมธอด clear() ช่วยให้คุณล้างข้อมูลทั้งหมดจาก StorageArea ได้
onChanged
เหตุการณ์ onChanged ช่วยให้คุณตรวจสอบการเปลี่ยนแปลงใน StorageArea ได้
กรณีการใช้งาน
ส่วนต่อไปนี้แสดง Use Case ทั่วไปสำหรับ 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 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 = 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
ระดับการเข้าถึงของพื้นที่เก็บข้อมูล
ค่าแจกแจง
"TRUSTED_CONTEXTS"
ระบุบริบทที่มาจากส่วนขยายเอง
"TRUSTED_AND_UNTRUSTED_CONTEXTS"
ระบุบริบทที่มาจากภายนอกส่วนขยาย
StorageChange
พร็อพเพอร์ตี้
-
newValue
ไม่บังคับ
ค่าใหม่ของรายการ (หากมี)
-
oldValue
ไม่บังคับ
ค่าเดิมของรายการ หากมีค่าเดิม
พร็อพเพอร์ตี้
local
รายการในพื้นที่เก็บข้อมูล local จะอยู่ในเครื่องแต่ละเครื่อง
ประเภท
StorageArea และออบเจ็กต์
พร็อพเพอร์ตี้
-
QUOTA_BYTES
10485760
ปริมาณข้อมูลสูงสุด (เป็นไบต์) ที่จัดเก็บในพื้นที่เก็บข้อมูลในเครื่องได้ โดยวัดจากสตริง JSON ของทุกค่าบวกกับความยาวของทุกคีย์ ระบบจะไม่สนใจค่านี้หากส่วนขยายมีสิทธิ์
unlimitedStorageการอัปเดตที่ทำให้เกินขีดจำกัดนี้จะล้มเหลวทันทีและตั้งค่าruntime.lastErrorเมื่อใช้ Callback หรือ Promise ที่ถูกปฏิเสธหากใช้ async/await
managed
รายการในพื้นที่เก็บข้อมูล managed จะกำหนดโดยนโยบายองค์กรที่กำหนดค่าโดยผู้ดูแลระบบโดเมน และเป็นแบบอ่านอย่างเดียวสำหรับส่วนขยาย การพยายามแก้ไขเนมสเปซนี้จะทำให้เกิดข้อผิดพลาด ดูข้อมูลเกี่ยวกับการกำหนดค่านโยบายได้ที่ไฟล์ Manifest สำหรับพื้นที่เก็บข้อมูล
ประเภท
session
ระบบจะจัดเก็บรายการในพื้นที่เก็บข้อมูล 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สูงสุดที่ทำได้ในแต่ละชั่วโมง ซึ่งเท่ากับ 1 ครั้งทุกๆ 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
browser.storage.onChanged.addListener(
callback: function,
)
เริ่มทำงานเมื่อมีการเปลี่ยนแปลงสินค้าอย่างน้อย 1 รายการ
พารามิเตอร์
-
callback
ฟังก์ชัน
พารามิเตอร์
callbackจะมีลักษณะดังนี้(changes: object, areaName: string) => void
-
การเปลี่ยนแปลง
ออบเจ็กต์
-
areaName
สตริง
-