مقدمه

در درس قبل دیدیم که کوکی‌ها با وجود کاربردی بودن برای مدیریت نشست، دارای محدودیت‌هایی جدی از جمله حجم کم و سربار شبکه هستند. برای حل این مشکلات و فراهم کردن یک راه حل بهتر برای ذخیره‌سازی داده‌ها در سمت کلاینت، استاندارد HTML5 تکنولوژی Web Storage را معرفی کرد. این تکنولوژی یک API بسیار ساده و با ظرفیت ذخیره‌سازی بسیار بیشتر (معمولاً ۵ تا ۱۰ مگابایت برای هر مبدأ) ارائه می‌دهد و برخلاف کوکی‌ها، داده‌های آن به صورت خودکار با هر درخواست HTTP به سرور ارسال نمی‌شوند.

Web Storage شامل دو مکانیزم مجزا اما با رابط کاربری یکسان است: localStorage و sessionStorage.

رابط کاربری ساده Web Storage

هر دوی localStorage و sessionStorage از یک API مشترک و بسیار ساده برای ذخیره و بازیابی داده‌ها به صورت زوج‌های کلید-مقدار (key-value) استفاده می‌کنند. مقادیر ذخیره شده باید به صورت رشته باشند. این API شامل متدهای زیر است:

  • setItem(key, value): یک آیتم جدید با کلید و مقدار مشخص شده را ذخیره می‌کند یا اگر کلید از قبل وجود داشته باشد، مقدار آن را به‌روزرسانی می‌کند.
  • getItem(key): مقدار مربوط به کلید مشخص شده را برمی‌گرداند. اگر کلید وجود نداشته باشد، `null` برمی‌گرداند.
  • removeItem(key): آیتم با کلید مشخص شده را حذف می‌کند.
  • clear(): تمام آیتم‌های ذخیره شده برای آن مبدأ را حذف می‌کند.
  • length: یک پراپرتی که تعداد کل آیتم‌های ذخیره شده را نشان می‌دهد.
Copy Icon JAVASCRIPT
// The API is identical for both localStorage and sessionStorage
// Let's use localStorage for this example.

// 1. Set an item
localStorage.setItem('theme', 'dark');
localStorage.setItem('language', 'fa');

// 2. Get an item
const currentTheme = localStorage.getItem('theme');
console.log('Current theme:', currentTheme); // "dark"

// 3. Get the number of stored items
console.log('Items stored:', localStorage.length); // 2

// 4. Remove a specific item
localStorage.removeItem('language');

// 5. Clear all items
// localStorage.clear();

همانطور که می‌بینید، این API بسیار ساده‌تر و خواناتر از کار با رشته document.cookie است. علاوه بر این متدها، می‌توان از سینتکس دسترسی به پراپرتی‌های شیء نیز استفاده کرد (مثلاً `localStorage.theme = 'dark'`) اما استفاده از متدها به دلیل وضوح بیشتر، توصیه می‌شود.

تفاوت localStorage و sessionStorage

با وجود API یکسان، تفاوت اصلی بین این دو مکانیزم در طول عمر و قلمرو (scope) داده‌های ذخیره شده است.

localStorage

داده‌های ذخیره شده در localStorage دائمی هستند. این داده‌ها تاریخ انقضا ندارند و تا زمانی که به صورت دستی توسط کاربر (از طریق تنظیمات مرورگر) یا توسط وب اپلیکیشن (با removeItem() یا clear()) حذف نشوند، باقی می‌مانند، حتی پس از بستن و باز کردن مجدد مرورگر. داده‌های localStorage به مبدأ (origin) یک وب‌سایت گره خورده‌اند و بین تمام تب‌ها و پنجره‌های باز از همان مبدأ به اشتراک گذاشته می‌شوند.

کاربردها: ذخیره تنظیمات کاربر (مانند تم تیره/روشن)، به خاطر سپردن وضعیت لاگین کاربر (البته بدون ذخیره توکن‌های حساس)، یا نگهداری داده‌های یک سبد خرید.

sessionStorage

داده‌های ذخیره شده در sessionStorage موقت هستند و تنها تا پایان «نشست صفحه» (page session) دوام می‌آورند. یک نشست صفحه تا زمانی که تب یا پنجره مرورگر باز است، ادامه دارد. به محض بسته شدن تب، تمام داده‌های sessionStorage مربوط به آن تب از بین می‌روند. همچنین، داده‌های sessionStorage برای هر تب مجزا هستند و بین تب‌های مختلف (حتی از یک مبدأ) به اشتراک گذاشته نمی‌شوند.

کاربردها: ذخیره داده‌های یک فرم چندمرحله‌ای (تا کاربر با رفرش کردن صفحه اطلاعاتش را از دست ندهد)، یا نگهداری وضعیت موقت یک رابط کاربری در طول یک بازدید.

ذخیره‌سازی اشیاء و آرایه‌ها

یک محدودیت مهم Web Storage این است که فقط می‌تواند مقادیر رشته‌ای را ذخیره کند. اگر سعی کنید یک شیء یا آرایه را مستقیماً در آن ذخیره کنید، به رشته `"[object Object]"` تبدیل خواهد شد و داده‌های شما از بین می‌رود.

راه‌حل استاندارد برای این مشکل، استفاده از `JSON` است. قبل از ذخیره کردن یک شیء یا آرایه، آن را با JSON.stringify() به یک رشته JSON تبدیل می‌کنیم. هنگام خواندن داده نیز، رشته را با JSON.parse() دوباره به شیء یا آرایه جاوااسکریپت تبدیل می‌کنیم.

Copy Icon JAVASCRIPT
const userPreferences = {
    theme: 'dark',
    notifications: { email: true, sms: false },
    bookmarks: [12, 45, 102]
};

// 1. Stringify the object and store it
localStorage.setItem('userPrefs', JSON.stringify(userPreferences));

// 2. Retrieve the string and parse it back into an object
const savedPrefsString = localStorage.getItem('userPrefs');
const savedPrefsObject = JSON.parse(savedPrefsString);

console.log(savedPrefsObject.notifications.email); // true

این الگوی `stringify/parse` برای کار با داده‌های ساختاریافته در Web Storage یک امر ضروری و رایج است.

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