גישה אסינכרונית לקובצי cookie של HTTP

ויקטור קוסטן

מהו ממשק ה-API של חנות קובצי cookie?

Cookie Store API חושף קובצי cookie של HTTP לעובדי השירות ומציע חלופה אסינכרונית ל-document.cookie. בעזרת ה-API קל יותר:

  • נמנעים מ-jank ב-thread הראשי על ידי גישה אסינכרונית לקובצי cookie.
  • לא כדאי לסרוק קובצי cookie, כי יכול להיות שיהיו שינויים בקובצי cookie.
  • קבלת גישה לקובצי cookie מ-Service Workers.

לקריאת ההסבר

הסטטוס הנוכחי

שלב סטטוס
1. יצירת הסבר הושלם
2. יצירת טיוטה ראשונית של מפרט הושלם
**3. אוספים משוב וחוזרים לפי המפרט** **בתהליך**
4. גרסת מקור לניסיון בהשהייה
5. הפעלה לא התחיל

איך משתמשים באחסון קובצי ה-cookie האסינכרוני?

הפעלה של גרסת המקור לניסיון

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

chrome --enable-blink-features=CookieStore

העברת הסימון הזה בשורת הפקודה מפעילה את ה-API באופן גלובלי ב-Chrome בסשן הנוכחי.

לחלופין, אפשר להפעיל את הדגל #enable-experimental-web-platform-features ב-chrome://flags.

אתם (ככל הנראה) לא צריכים קובצי cookie

לפני שנכנסים ל-API החדש, אני רוצה לציין שקובצי cookie הם עדיין הבסיס הגרוע ביותר של אחסון בצד הלקוח בפלטפורמת האינטרנט, וכדאי להמשיך להשתמש בהם כמוצא אחרון. זו לא טעות – קובצי cookie היו המנגנון הראשון לאחסון בצד הלקוח באינטרנט, ומאז למדנו הרבה.

הסיבות העיקריות להימנעות מקובצי cookie הן:

  • קובצי cookie מוסיפים את סכימת האחסון שלכם ל-API לקצה העורפי. כל בקשת HTTP נושאת תמונת מצב של מאגר קובצי ה-cookie. כך מהנדסי הקצה העורפי יכולים בקלות להוסיף תלות בפורמט הנוכחי של קובצי ה-cookie. כשזה קורה, ממשק הקצה לא יכול לשנות את סכימת האחסון שלו בלי לפרוס שינוי תואם בממשק העורפי.

  • לקובצי cookie יש מודל אבטחה מורכב. התכונות של פלטפורמת האינטרנט המודרנית פועלות לפי אותה מדיניות מקור, כלומר לכל אפליקציה יש ארגז חול משלה, והיא בלתי תלויה לחלוטין באפליקציות אחרות שהמשתמש מריץ. היקפי ההרשאות של קובצי ה-cookie יוצרים סיפור אבטחה מורכב יותר, והמטרה היא לנסות לסכם כך שיכפיל את הגודל של המאמר הזה.

  • לקובצי cookie יש עלויות גבוהות של ביצועים. דפדפנים צריכים לכלול תמונת מצב של קובצי ה-cookie בכל בקשת HTTP, כך שכל שינוי בקובצי ה-cookie חייב להתעדכן בסטאקים של האחסון והרשת. לדפדפנים מודרניים יש הטמעות של מאגרי קובצי cookie שעברו אופטימיזציה, אבל אף פעם לא נוכל לייעל את קובצי ה-cookie כמו שאר מנגנוני האחסון, שלא צריכים להשתמש בסטאק הרשת.

מכל הסיבות שלמעלה, אפליקציות אינטרנט מודרניות צריכות להימנע מקובצי cookie, ולאחסן מזהה סשן ב-IndexedDB, ולהוסיף את המזהה באופן מפורש לכותרת או לגוף של בקשות HTTP ספציפיות, באמצעות ממשק ה-API ל-fetch.

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

ה-API המכובד document.cookie הוא מקור מובטח למדי של jank לאפליקציה שלכם. לדוגמה, בכל פעם שמשתמשים ב-Takeer של document.cookie, הדפדפן צריך להפסיק לבצע JavaScript עד שהוא יכיל את נתוני קובץ ה-cookie שביקשת. הפעולה הזו עשויה לקחת תהליך דילוג או קריאת דיסק, ולגרום לבעיות בממשק המשתמש (jank).

פתרון פשוט לבעיה הוא מעבר מהמקבל document.cookie ל-Cookie Store API האסינכרוני.

await cookieStore.get('session_id');

// {
//   domain: "example.com",
//   expires: 1593745721000,
//   name: "session_id",
//   path: "/",
//   sameSite: "unrestricted",
//   secure: true,
//   value: "yxlgco2xtqb.ly25tv3tkb8"
// }

אפשר להחליף את הגורם המגדיר document.cookie באופן דומה. חשוב לזכור שיכול להיות שהשינוי יחול רק אחרי שההבטחה שהוחזרה על ידי cookieStore.set תסתיים.

await cookieStore.set({name: 'opt_out', value: '1'});

// undefined

צפייה, ללא סקרים

אפליקציה פופולרית לגישה לקובצי cookie מ-JavaScript מזהה כאשר המשתמש מתנתק ומעדכנת את ממשק המשתמש. כרגע מתבצע סקר document.cookie, שמציג בעיות בממשק (jank) ומשפיע לרעה על חיי הסוללה.

השימוש ב-Cookie Store API כולל שיטה חלופית לצפייה בשינויים בקובצי cookie, שלא מחייבת דגימה של קובצי cookie.

cookieStore.addEventListener('change', event => {
  for (const cookie of event.changed) {
    if (cookie.name === 'session_id') sessionCookieChanged(cookie.value);
  }
  for (const cookie of event.deleted) {
    if (cookie.name === 'session_id') sessionCookieChanged(null);
  }
});

עובדים בשירות קבלת פנים

בגלל תכנון סינכרוני, ה-API document.cookie לא זמין ל-Service Workers. ה-API של מאגר קובצי ה-cookie הוא אסינכרוני, ולכן הוא מותר לשימוש ב-Service Workers.

האינטראקציה עם קובצי ה-cookie פועלת באותו אופן בהקשרים של מסמכים וב-Service Workers.

// Works in documents and service workers.
async function logOut() {
  await cookieStore.delete('session_id');
}

עם זאת, אופן המעקב אחר שינויים בקובצי cookie שונה מעט ב-Service Workers. השכמה של קובץ שירות (service worker) יכולה להיות יקרה למדי, לכן עלינו לתאר באופן מפורש את השינויים בקובצי cookie שהעובד מעוניין בהם.

בדוגמה הבאה, אפליקציה שמשתמשת ב-IndexedDB כדי לשמור נתוני משתמשים במטמון, עוקבת אחר השינויים בקובץ ה-cookie של הסשן ומתנתקת מהנתונים שנשמרו במטמון כשהמשתמש מתנתק.

// Specify the cookie changes we're interested in during the install event.
self.addEventListener('install', event => {
  event.waitUntil(cookieStore.subscribeToChanges([{name: 'session_id'}]));
});

// Delete cached data when the user logs out.
self.addEventListener('cookiechange', event => {
  for (const cookie of event.deleted) {
    if (cookie.name === 'session_id') {
      indexedDB.deleteDatabase('user_cache');
      break;
    }
  }
});

שיטות מומלצות

בקרוב.

משוב

אם אתם רוצים לנסות את ה-API הזה, נשמח לשמוע מה דעתכם. עליכם להפנות את המשוב על צורת ה-API אל מאגר המפרט, ולדווח על באגים בהטמעה לרכיב Blink>Storage>CookiesAPI Blink.

אנחנו מעוניינים במיוחד ללמוד על מדידות של ביצועים ועל תרחישי שימוש, מעבר לאלה שתוארו במסביר.

משאבים נוספים