مقدمه

به فصل «ذخیره‌سازی داده‌ها در سمت کاربر» خوش آمدید. در این فصل با روش‌های مختلفی که به ما اجازه می‌دهند داده‌ها را مستقیماً در مرورگر کاربر ذخیره کنیم، آشنا می‌شویم. اولین و قدیمی‌ترین مکانیزم برای این کار، «کوکی‌ها» (Cookies) هستند. کوکی‌ها قطعات کوچکی از متن هستند که یک وب‌سایت می‌تواند روی کامپیوتر کاربر ذخیره کند. کاربرد اصلی آنها از ابتدا، مدیریت «حالت» (state) در پروتکل بی‌حالت HTTP بوده است؛ برای مثال، به یاد سپردن اینکه یک کاربر قبلاً لاگین کرده است (مدیریت نشست یا session management).

کوکی‌ها چگونه کار می‌کنند؟

مکانیزم کار کوکی‌ها بر اساس یک تعامل دوطرفه بین سرور و مرورگر است.

  1. تنظیم کوکی توسط سرور: وقتی شما برای اولین بار از یک وب‌سایت بازدید می‌کنید، سرور می‌تواند در پاسخ HTTP خود، یک هدر به نام Set-Cookie ارسال کند. این هدر حاوی نام، مقدار و اطلاعات دیگری درباره کوکی است.
  2. ذخیره‌سازی توسط مرورگر: مرورگر پس از دریافت این هدر، کوکی را برای آن دامنه خاص ذخیره می‌کند.
  3. ارسال مجدد به سرور: از آن پس، در هر درخواست بعدی که مرورگر به همان سرور ارسال می‌کند، به صورت خودکار کوکی‌های ذخیره شده را در یک هدر به نام Cookie قرار داده و به سرور می‌فرستد.

این فرآیند به سرور اجازه می‌دهد تا کاربران را شناسایی کرده و حالت آنها را در درخواست‌های مختلف حفظ کند.

کار با کوکی‌ها از طریق document.cookie

جاوااسکریپت می‌تواند به کوکی‌های یک صفحه از طریق پراپرتی document.cookie دسترسی داشته باشد. این پراپرتی یک رابط کاربری رشته‌ای و کمی عجیب دارد که کار با آن نیازمند دقت است.

نوشتن (ایجاد) یک کوکی

برای ایجاد یا به‌روزرسانی یک کوکی، کافیست یک رشته با فرمت key=value به document.cookie اختصاص دهیم. همچنین می‌توانیم با افزودن پارامترهای اضافی که با نقطه‌ویرگول (;) جدا می‌شوند، ویژگی‌های کوکی را تعیین کنیم:

  • expires=UTCString: تاریخ انقضای کوکی را به فرمت UTC مشخص می‌کند.
  • max-age=seconds: عمر کوکی را بر حسب ثانیه مشخص می‌کند.
  • path=/: مشخص می‌کند که کوکی برای کدام مسیرها در سایت معتبر است (مقدار `/` یعنی کل سایت).
  • secure: تضمین می‌کند که کوکی فقط از طریق اتصال امن HTTPS ارسال شود.
  • samesite=Strict|Lax|None: یک ویژگی امنیتی برای مقابله با حملات CSRF.
Copy Icon JAVASCRIPT
function setCookie(name, value, days) {
    let expires = "";
    if (days) {
        const date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "")  + expires + "; path=/";
}

setCookie('username', 'JohnDoe', 7); // Sets a cookie named 'username' that expires in 7 days

این تابع کمکی، فرآیند ساخت رشته کوکی را ساده‌تر می‌کند. با فراخوانی آن، یک کوکی به نام username با مقدار JohnDoe و تاریخ انقضای ۷ روز دیگر در مرورگر کاربر ذخیره می‌شود.

خواندن کوکی‌ها

خواندن document.cookie یک رشته واحد برمی‌گرداند که شامل تمام کوکی‌های آن دامنه است و با نقطه‌ویرگول از هم جدا شده‌اند (مثلاً 'username=JohnDoe; theme=dark'). برای به دست آوردن مقدار یک کوکی خاص، باید این رشته را خودمان پردازش کنیم.

Copy Icon JAVASCRIPT
function getCookie(name) {
    const nameEQ = name + "=";
    const ca = document.cookie.split(';');
    for(let i = 0; i < ca.length; i++) {
        let c = ca[i];
        while (c.charAt(0) === ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
}

const username = getCookie('username');
console.log('Username from cookie:', username); // "JohnDoe"

تابع کمکی getCookie رشته کوکی‌ها را گرفته، آن را به بخش‌های مجزا تقسیم کرده و با پیمایش آنها، مقدار کوکی با نام مورد نظر را پیدا و برمی‌گرداند.

حذف یک کوکی

هیچ متد مستقیمی برای حذف کوکی وجود ندارد. ترفند حذف یک کوکی این است که آن را با همان نام دوباره تنظیم کنیم، اما تاریخ انقضای آن را در گذشته قرار دهیم (یا از Max-Age با مقدار منفی استفاده کنیم). مرورگر با دیدن تاریخ انقضای گذشته، کوکی را به صورت خودکار حذف می‌کند.

Copy Icon JAVASCRIPT
function deleteCookie(name) {
    document.cookie = name + '=; Max-Age=-99999999; path=/;';
}

// deleteCookie('username');

محدودیت‌ها و جایگزین‌های مدرن

با وجود کاربردی بودن، کوکی‌ها دارای معایب و محدودیت‌های قابل توجهی هستند:

  • اندازه کوچک: هر کوکی به حدود ۴ کیلوبایت محدود است و تعداد کل کوکی‌ها برای هر دامنه نیز محدودیت دارد.
  • سربار شبکه: کوکی‌ها با هر درخواست HTTP به سرور ارسال می‌شوند، حتی اگر برای آن درخواست خاص نیازی به آنها نباشد. این کار پهنای باند را هدر می‌دهد.
  • رابط کاربری نامناسب: همانطور که دیدید، کار با رشته document.cookie برای عملیات ساده نیز نیازمند نوشتن توابع کمکی است.

به دلیل این محدودیت‌ها، برای ذخیره‌سازی عمومی داده‌ها در سمت کلاینت، امروزه از جایگزین‌های مدرن‌تری استفاده می‌شود.

در این درس با کوکی‌ها، به عنوان اولین مکانیزم ذخیره‌سازی سمت کلاینت، و نحوه کار با آنها آشنا شدیم. همانطور که دیدیم، کوکی‌ها برای مدیریت نشست و ارسال داده‌های کوچک به سرور مفید هستند، اما محدودیت‌های قابل توجهی دارند. در درس بعدی، به سراغ «تکنولوژی Web Storage» خواهیم رفت که شامل localStorage و sessionStorage می‌شود و یک API بسیار ساده‌تر و با ظرفیت بیشتر برای ذخیره‌سازی داده‌ها در مرورگر ارائه می‌دهد.