ข้ามไปยังเนื้อหา

Cookie Store API

document.cookie เป็น synchronous API ที่ออกแบบในช่วงกลางทศวรรษ 1990 มีจุดที่น่าหงุดหงิดสามอย่าง:

  1. ต้อง parse เอง — การอ่าน cookie ตามชื่อต้องแยก string และวนลูป
  2. การเขียนใช้ string — ต้องสร้าง cookie string ด้วยตัวเอง
  3. ไม่มี change event — ไม่มีวิธีสังเกตเมื่อแท็บอื่นหรือ server เปลี่ยน cookie

Cookie Store API แก้ปัญหาทั้งสามด้วย interface ที่สะอาดแบบ Promise-based

Cookie Store API มีใน Chrome และ Edge (browser ที่ใช้ Chromium) แต่ Firefox ยังไม่รองรับ ควรตรวจสอบการรองรับก่อนใช้เสมอ

คืน Promise ที่ resolve เป็น object CookieListItem หรือ null ถ้า cookie ไม่มีอยู่:

const cookie = await cookieStore.get('theme');
if (cookie) {
console.log(cookie.name); // 'theme'
console.log(cookie.value); // 'dark'
}

object ที่คืนยังมี property domain, path, expires, secure, sameSite, และ httpOnly ด้วย

รับคู่ name/value เป็น string หรือ object options:

// รูปแบบสั้น
await cookieStore.set('theme', 'dark');
// รูปแบบ options — แนะนำสำหรับควบคุม attribute
await cookieStore.set({
name: 'theme',
value: 'dark',
maxAge: 86400,
sameSite: 'lax',
});

คืน Promise ที่ resolve เมื่อ cookie ถูกเขียนแล้ว

await cookieStore.delete('theme');

คืน Promise ที่ resolve เมื่อ cookie ถูกลบ เทียบเท่ากับการตั้ง Max-Age=0

const allCookies = await cookieStore.getAll();
allCookies.forEach(c => console.log(c.name, c.value));

ต่างจาก document.cookie ตรงที่คืน array ของ object จริงๆ — ไม่ต้อง parse string

Cookie Store API ช่วยให้ฟัง cookie change แบบ reactive ได้:

cookieStore.addEventListener('change', event => {
event.changed.forEach(c => {
console.log('Cookie changed:', c.name, '=', c.value);
});
event.deleted.forEach(c => {
console.log('Cookie deleted:', c.name);
});
});

event.changed เป็น array ของ cookie ที่ถูกตั้งค่าหรืออัปเดต event.deleted เป็น array ของ cookie ที่ถูกลบ ทำงานข้ามแท็บสำหรับ cookie ที่ไม่ได้จำกัดขอบเขตไว้ที่แท็บเดียว

เนื่องจากการรองรับ browser ยังไม่ครบ ควร feature-detect และ fallback ไปใช้ document.cookie เสมอ:

async function getTheme() {
if ('cookieStore' in window) {
const c = await cookieStore.get('theme');
return c ? c.value : null;
} else {
// fallback document.cookie
var pairs = document.cookie.split('; ');
for (var i = 0; i < pairs.length; i++) {
var p = pairs[i].split('=');
if (p[0] === 'theme') return decodeURIComponent(p[1]);
}
return null;
}
}
Browser Storage
ตัวเลือกBenefitCost
Cookie Store APIโค้ดสั้นและอ่านง่ายกว่ามาก — await cookieStore.get() แทนการ split string เอง แถมมี change event ให้ฟังแบบ reactiveFirefox ยังไม่รองรับ ต้อง feature-detect และเขียน fallback ไปใช้ document.cookie เสมอ เพิ่มโค้ดสองชุดสำหรับ logic เดียวกัน
document.cookieรองรับทุก browser ไม่ต้องมี fallbackเป็น synchronous string API ต้อง parse เองทุกครั้ง ไม่มี change event ในตัว
  • เรียก cookieStore.get()/.set() โดยไม่ feature-detect ก่อน — โค้ดจะพังทันทีบน Firefox เพราะ cookieStore ไม่มีอยู่ใน window
  • ลืมว่า method ของ Cookie Store API เป็น async ทั้งหมด — เขียนโค้ดราวกับว่าค่าคืนกลับมาแบบ synchronous แล้วได้ Promise object แทนค่าจริง ต้อง await เสมอ
  • คาดหวังว่า change event จะทำงานเหมือนกันทุก browser และทุกสถานการณ์ — พฤติกรรมข้ามแท็บของ event นี้ยังไม่ได้มาตรฐานเดียวกันในทุก implementation ควรทดสอบจริงก่อนพึ่งพาเป็น core logic

💡 ตัวอย่างจากของจริง

แอปที่ sync ค่า theme/preference ข้ามแท็บ — ใช้ cookieStore.addEventListener('change', ...) เพื่ออัปเดต UI ทันทีเมื่อผู้ใช้เปลี่ยนค่าในแท็บอื่น โดยไม่ต้อง poll หรือ reload

Progressive enhancement บนเว็บ production — ทีมที่ต้องรองรับทั้ง Chrome/Edge และ Firefox มักเขียน wrapper function ที่ feature-detect cookieStore แล้ว fallback ไป document.cookie เพื่อให้โค้ด business logic เขียนครั้งเดียวใช้ได้ทุก browser

cookieStore.get(name) คืนค่าอะไรเมื่อคุกกี้มีอยู่?
browser ใดที่ยังไม่รองรับ Cookie Store API?
วิธีฟัง cookie change ด้วย Cookie Store API คือ?