کار با کوکی ها در جاوا اسکریپت

12 اردیبهشت 1398
Advanced-Javascript-cookies

کوکی چیست؟

امکان ندارد در دنیای مجازی قدم گذاشته باشید اما هیچ گاه کلمه ی کوکی (Cookie) را نشنیده یا ندیده باشید. تعریف کوکی ها به این شکل است:

An HTTP cookie (also called web cookieInternet cookiebrowser cookie, or simply cookie) is a small piece of data sent from a website and stored on the user's computer by the user's web browser while the user is browsing.

کوکیِ HTTP (که با نام های کوکی وب، کوکی اینترنتی، کوکی مرورگر یا فقط کوکی نیز شناخته می شود) قسمت کوچکی از اطلاعات است که از سمت یک وب سایت به مرورگر کاربر فرستاده شده و در آن ذخیره می شود.

در واقع کوکی ها فایل های متنی کوتاهی هستند که در مرورگر شما ذخیره شده اند. حالا زمانی که یک صفحه ی وب از سمت سرور به مرورگر شما ارسال می شود، اتصال از بین می رود. چرا؟ به این دلیل که HTTP یک پروتکل فراموشکار است و در شرایط طبیعی هرگز گذشته‌اش را به خاطر نمی‌آورد. یعنی اگر شما ده‌ها فرمان HTTP به سوی سرویس دهنده بفرستید هیچ ارتباط منطقی بین آن‌ها تشخیص نخواهد داد و کاربر را به خاطر نخواهد آورد. کلید حل این مسئله بهره‌گیری از مکانیزمی برای ایجاد یک نشست (session) بین مرورگر و سرویس دهندهٔ وب است.

به زبان ساده تر کوکی ها اختراع شدند تا اطلاعات کاربر را به خاطر بسپارند؛ به طور مثال زمانی که کاربری از یک صفحه ی اینترنتی بازدید می کند نام او می تواند به صورت یک کوکی ذخیره شود و سپس در دفعات بعدی به خاطر آورده شود.

کوکی ها به صورت جفت های name/value ذخیره می شوند مانند:

username = John Doe

معمولا زمانی که یک مرورگر یک صفحه ی وب را از سروری درخواست می کند، یک یا چند کوکی نیز به همراه آن صفحه ی وب به سمت مرورگر کاربر ارسال می شوند. بدین صورت سرور می تواند بعدا این کاربر را به یاد بیاورد. البته باید به یاد داشته باشید که اگر قابلیت کوکی ها را در مرورگر خود غیر فعال کرده باشید هیچ کدام از این قابلیت ها برای شما کار نخواهد کرد.

ساخت کوکی با جاوا اسکریپت

زبان های سمت سرور تنها راه ایجاد کوکی نیستند و ما می توانیم با جاوا اسکریپت نیز کوکی ایجاد کنیم. ما این کار را با خصوصیت document.cookie انجام می دهیم. به طور مثال یک کوکی به نام John Doe می سازیم:

document.cookie = "username=John Doe";

همچنین می توانید یک تاریخ انقضا برای کوکی هایتان در نظر بگیرید تا پس از آن تاریخ کوکی ها حذف شوند. در حالت عادی کوکی ها پس از بستن مرورگر حذف خواهند شد:

document.cookie = "username=John Doe; expires=Thu, 18 Dec 2020 12:00:00 UTC";

شما می توانید مسیر یا path کوکی را نیز انتخاب کنید. مسیر کوکی مشخص می کند که کوکی در چه صفحاتی از یک وب سایت قابل دسترسی باشد. در حالت پیش فرض کوکی ها متعلق به صفحه ای هستند که کاربر در آن قرار دارد:

document.cookie = "username=John Doe; expires=Thu, 18 Dec 2020 12:00:00 UTC; path=/";

اگر خواستید کوکی های از قبل ایجاد شده را با جاوا اسکریپت بخوانید می توانید از ساختار زیر استفاده کنید:

var x = document.cookie;

این دستور (یعنی document.cookie) تمام کوکی های کاربر را در یک رشته بر میگرداند، به طور مثال: ;cookie1=value; cookie2=value; cookie3=value

برای تغییر این کوکی ها نیز می توانید از این ساختار استفاده کنید:

document.cookie = "username=John Smith; expires=Thu, 18 Dec 2020 12:00:00 UTC; path=/";

به این ترتیب کوکی ما ویرایش می شود و دیگر نام کاربری John Doe نخواهد بود.

در آخر اگر قصد حذف کامل یک کوکی را داشته باشید باید تاریخ انقضاء آن را به گذشته تغییر دهید، یعنی زمانی در گذشته:

document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";

حالا که تاریخ انقضاء کوکی را در سال 1970 قرار داده ایم، مرورگر سریعا آن را حذف می کند.

نکته: در برخی از مرورگر ها اگر مسیر (path) کوکی را به درستی مشخص نکنید، اجازه ی حذف آن را به شما نمی دهند. همچنین مشخص کردن path به شما کمک می کند که کوکی درست را حذف کرده و اشتباها تمام کوکی ها را حذف نکنید.

رشته های کوکی

خصوصیت document.cookie شبیه به یک رشته ی متنی ساده است اما در واقعیت اینطور نیست. چرا که اگر شما یک رشته کوکی کامل را بنویسید و به document.cookie بدهید، هنگام بازخوانی آن ها تنها می توانید مقادیر name / value را ببینید. همچنین اگر یک کوکی جدید بنویسید، کوکی های قدیمی overwrite (حذف و جایگزین) نمی شوند بنابراین اگر document.cookie را بخوانید با چیزی شبیه به این روبرو می شوید:

cookie1 = value; cookie2 = value;

با این تفاسیر اگر بخواهید مقدار یک کوکی را بخوانید باید تابعی بنویسید که به دنبال آن کوکی بگردد. بیایید چند مثال را ببینیم.

مثال کاربردی

در مثال زیر ابتدا می خواهیم یک کوکی ایجاد کنیم که نام کاربر را دریافت می کند. در واقع اگر کاربر دفعه ی اولی باشد که به سایت ما سر میزند از او می خواهیم که نام اش را به ما بگوید و آن را به صورت کوکی ذخیره می کنیم. سپس دفعه ی بعدی که به سایت ما سر بزند، یک پیام خوش آمد گویی با نام خودش به او نشان می دهیم.

برای اجرای این مثال به سه تابع نیاز داریم:

  • یک تابع برای ساخت کوکی
  • یک تابع برای دریافت کوکی
  • یک تابع برای چک کردن مقدار کوکی

تابع اول: ساخت کوکی

function setCookie(cname, cvalue, exdays) {
  var d = new Date();
  d.setTime(d.getTime() + (exdays*24*60*60*1000));
  var expires = "expires="+ d.toUTCString();
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

پارامتر های این تابع به ترتیب نام کوکی (cname)، مقدار کوکی (cvalue) و تاریخ انقضاء کوکی (exdays) هستند. این تابع هر سه این پارامتر ها را ترکیب می کند و کوکی مورد نظر را می سازد.

تابع دوم: دریافت کوکی

حالا باید تابعی بسازیم که مقدار کوکی را برگرداند:

function getCookie(cname) {
  var name = cname + "=";
  var decodedCookie = decodeURIComponent(document.cookie);
  var ca = decodedCookie.split(';');
  for(var i = 0; i <ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

در این کد ابتدا نام کوکی (cname) را به عنوان یک پارامتر گرفته ایم و سپس یک متغیر (name) را به همراه متنی برای جست و جو ("=" + cname) ایجاد کرده ایم. سپس رشته ی کوکی را باز کرده ایم تا کوکی ها را با کاراکتر های خاص مدیریت کنیم. حالا document.cookie را با علامت ; جداسازی می کنیم و در یک آرایه به نام ca قرار می دهیم (دستور (';')ca = decodedCookie.split). سپس در آرایه ی ca گردش می کنیم و تک تک مقادیر را میگیریم ([c = ca[i). حالا می گوییم اگر کوکی پیدا شد (c.indexOf(name) == 0) مقدار آن را برگردان (c.substring(name.length, c.length) اما اگر مقدار کوکی پیدا نشد "" را برگردان.

تابع سوم: چک کردن کوکی

حالا باید تابعی بسازیم که کوکی را چک کند. اگر کوکی تنظیم شده باشد یک پیام خوش آمد گویی را نمایش می دهد اما اگر کوکی نداشته باشیم یک prompt box ظاهر می شود که نام کاربر را از او می گیرد. سپس کوکی را می سازد و آن را با دستور setCookie  تا 365 روز نگه می دارد (تاریخ انقضاء). به کد زیر نگاه کنید:

function checkCookie() {
  var username = getCookie("username");
  if (username != "") {
   alert("Welcome again " + username);
  } else {
    username = prompt("Please enter your name:", "");
    if (username != "" && username != null) {
      setCookie("username", username, 365);
    }
  }
}

کد تکمیل شده و نهایی

کد تکمیل شده و کامل ما به این شکل است:

<!DOCTYPE html>
<html>
<head>
<script>
function setCookie(cname,cvalue,exdays) {
  var d = new Date();
  d.setTime(d.getTime() + (exdays*24*60*60*1000));
  var expires = "expires=" + d.toGMTString();
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

function getCookie(cname) {
  var name = cname + "=";
  var decodedCookie = decodeURIComponent(document.cookie);
  var ca = decodedCookie.split(';');
  for(var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

function checkCookie() {
  var user=getCookie("username");
  if (user != "") {
    alert("Welcome again " + user);
  } else {
     user = prompt("Please enter your name:","");
     if (user != "" && user != null) {
       setCookie("username", user, 30);
     }
  }
}
</script>
</head>

<body onload="checkCookie()"></body>

</html>

مشاهده ی خروجی در JSBin

به خروجی بالا بروید و نام خود را به prompt box بدهید. سپس یک بار صفحه ی خروجی را refresh کنید تا با پیام خوش آمد گویی مواجه شوید.

امیدوارم از این قسمت لذت برده باشید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری جاوا اسکریپت پیشرفته توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

کیوان
29 بهمن 1398
درود و احترام خدمت شما جناب زوارمی عزیز و تیم محترم روکسو خواستم بپرسم در بعضی سایت ها مثلا سیستم لایکشون برای کاربرهای مهمان فعال هست و بدون عضویت شما میتونین لایک کنید اما هر پست رو فقط یک بار میتونید لایک کنید چون کوکی یا سشن تنظیم کردند حالا اگر ما کوکی رو حذف کنیم دوباره میتونیم همون پست رو چندین بار با حذف کوکی لایک کنیم خواستم بدونم دقیقا از چه روشی استفاده میشود آیا کوکی ما در دیتابسشون ذخیره شده و هنگام لایک کردن کوکی کاربر رو از دیتابیس چک میکنند؟ یا کاری به دیتابس ندارند؟ دقیقا متوجه کارشون نمیشم با تشکر فراوان

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امیر زوارمی
04 اسفند 1398
سلام دوست عزیز، کوکی رو معمولا هیچ وقت روی دیتابیس ذخیره نمی کنند. کوکی یک چیز مخصوص مرورگر هست و معادل اون در سرور میشه همون Session. اگر کوکی روی سرور ذخیره می شد دیگه شما نمی تونستید با حذف کردن کوکی دوباره لایک کنید. چرا؟ چون شما دسترسی به سرور اون ها ندارید. اینطور نیست که شما با پاک کردن کوکی های مرورگر خودتون، به سرور اون ها دستور بدید که کوکی رو پاک کنه. اینطور وب سایت ها از کوکی های عادی استفاده می کنن که روی مرورگر شما ذخیره میشه بنابراین وقتی کوکی ها رو پاک می کنید، دیگه وب سایت تشخیص نمی ده که شما قبل لایک کردید. وب سایت هایی که سفت و سخت تر می گیرن، بر اساس حساب کاربری و عضویت شما اجازه ی لایک می دن که خب موضوعش مشخصه (کاربر X قبلا لایک کرده پس اجازه ی لایک دوباره نداره - کاربر Y عضو نیست پس اصلا اجازه ی عضویت نداره)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.