ماهي الـ Cookies ؟
عندما أقول Cookies فأنا لا أقصد بذلك Americana Cookies وعندما أقول كعكات فأنا لا أقصد بذلك كعكات العيد أو حتى أي نوع من أنواع الكعك ..!
في عالم تطبيقات الويب كلمة Cookies تعني ملفات نصيه صغيرة الحجم تتنقل ما بين الخادم Server والعميل Client تحوي على معلومات يستطيع تطبيق الويب قراءتها وغالبا ما يحتاجها.
عندما يطلب المتصفح صفحة من موقع ماوليكن على سبيل المثال dev4arabs.com فإن الخادم Server لا يقوم بإرسال الصفحة فقط بل إنه يقوم بأرسال الصفحة بالإضاقة الى Cookies\ الكعكات. فيقوم المتصفح باستقبال الصفحة وعرضها و استقبال الـ Cookies وحفظها على داخل مجلد معين .
بعد ذلك عندما يقوم المستخدم بكتابة عنوان الموقع dev4arabs.com يقوم المتصفح بالبحث داخل المجلد الذي يحوي الـ Cookies فـإن وجد شيئا تابعا للموقع أرسله للخادم وذلك ليتسنى لتطبيق الويب من قراءة المعلومات الموجودة داخل هذه الـ Cookies.
تذكر دائما أن الـ Cookies مرتبطة بالموقع ككل لا بصفحة معينه فالخادم و العميل سيتبادلان الـ Cookies حالما المستخدم في الموقع بغض النظر عن الصفحة التي يتصفحها .
ربما يدفعك فضول كبير لمعرفة سبب تسمية الـ Cookies بهذا الإسم, لذا أنصحك بزيارة هذا الموقع http://www.catb.org/~esr/jargon/jargon.html#cookie.
حدود من الصعب تجاوزها
قبل أن نشرع في التعامل مع الـ Cookies أو أن أذكر لك محظورات الـ Cookies أوالحدود التي يصعب على الـ Cookies تعديها , مثل :
•معظم المتصفحات لا تسمح ان يكون حجم الكعكه الواحد أكثر من 4096 بايت وفي الحقيقة لا أعتقد بأنك ستحتاج لهذا الرقم ..!
•معظم المتصفحات لا تسمح بأكثر من 20 كعكه Cookie للموقع الواحد وان زادت ستستبدل أقدمها بأجددها .
•بعض المتصفحات تضع الرقم 300 لتعبر به عن عدد الكعكات التي يمكن استقبالها من جميع الـمواقع.
بالطبع هذه المحظورات التي قرأتها ستكون فقط عندما يسمح لنا المستخدم باستخدام الـ Cookies في متصفحه .
الان وبعد أن اخذنا نطرة عامة عن الـ Cookies ومحظوراتها سنبدأ بالتعامل معها.
إنشاء الـ Cookies في ASP.NET
إنشاء أو كتابة الـ Cookies يتم عن طريق الخاصيه Response Property والتابعة للكائن Page Object, الخاصية Response والتي تمثل كائنا بحد ذاتها تمكننا من كتابة وارسال الأوامر للمتصفح الذي يقوم بدوره بترجمة هذه الأوامر وعرضها. كما تحوي على Collection يسمى Cookies يساعدنا على كتبابة الـ Cookies إلى جهاز المستخدم.
عندما تقوم بإنشاء Cookie فأنت تقوم أولا بتحديد بعض المعلومات عن هذه الـ Cookie مثل الاسم والمعلومات التي تود تخزينها.
لا تنسى عزيزي بأن اسم الـCookie مهم جدا جدا لأن عملية التمييز بين الـ Cookies تتم بواسطة الاسم فإذا كان لكعكتين نفس الاسم فستستبدل واحده بأخرى (Overwriting) .
أيضا يمكنك تحديد تاريخ ووقت انتهاء هذه الـ Cookie فهي كما تعلم تخزن على جهاز المستخدم و هذا يعني أنها ستبقى على موجوده على جهازه للأبد ( مالم يحذفها هو بالطبع) فعند وصول الكعكه لتاريخ الانتهاء تصبح غير صالحة للأستخدام – حرصا على سلامة الجميع – فلا يقوم المتصفح بإرسال هذه الكعكة الى الـخادم Server كما أنه يقوم بحذفها من مجلد الـ cookies .
يمكنك انشاء أكثر من Cookie في نفس الوقت وتحديد تاريخ ووقت لانتهاء كل منهم بشكل مستقل.
ربما أنت تسأل نفسك عن المده التي يجب ان اضعها لكعكاتي هل هي يوم ..يومين .. شهر..!!! هذا الأمر عزيزي يرجع لمدى استخدامك لهذه الـ Cookie فعلى سبيل المثال تريد عمل عداد يحسب لك عدد زيارات المستخدم لمدة شهر ففي هذه الحاله ستكون المدة شهر .. وهكذا ..
هذه الفتره سواء كانت طويله أو قصيره فهي بدون جدوى اذا قام مستخدم الجهاز بحذف هذه الـ Cookies فهي تعتبر رهن تصرفه !
إن لم تقم بتحديد تاريخ الانتهاء لكعكة ما فستنشأ بشكل طبيعي ولكنها لن تخزن بالقرص الصلب لجهاز المستخدم بل انها تخزن كجزء من User’s Session - جلسة المستخدم - وفي حال إغلاق المتصفح أو انتهاء الوقت الاقتراضي للجلسة فأن هذه الـ Cookie تحذف, يطلق على هذا النوع من الـكعكات Non-persistent Cookies وهو مفيد في تخزين المعلومات التي لا تحتاج لأن تمكث لوقت طويل.
يمكنك اضافة Cookie للـ Cookies Collection بطريقتين الأولى :
Response.Cookies("firstName").Value = "Ayman"
Response.Cookies("firstName ").Expires = DateTime.Now.AddDays(1)الطريقة الثانية :
Dim myCookie As New HttpCookie("lastVisit")
myCookie.Value = DateTime.Now.ToString
myCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(myCookie)في الطريقة الأولى قمت بإسناد القيم Repsonse.Cookies مباشرة أما في الطريقة الثانية فقد قمت بعمل نسخه Instance من الكائن httpCookie وبعد ذلك عدلت بعض خواصه, ومن ثم أضفته للـ Cookies باستخدام الطريقة Add Method . لاحظ أنه عند عمل نسخه من الكائن httpCookie يلزمك تمرير اسم الـ Cookie كجزء من الـ Constructor .
كلا الطريقتين صحيحه ولكن الطريقه الثانيه مرنه أكثرمن ناحية تتعديل الخواص.
القيم التي تخزن في الـCookie تكون على شكل String لذا لزمنا تحويل قيمة الـ lastVisit من نوع DateTime الى String بالسطر التالي :
myCookie.Value = DateTime.Now.ToString
الـCookies ذوات القيم المتعددة
في المثال السابق قمنا بإنشاء ملفي cookie الأول لتحمل الاسم الأول والثاني لتحمل تاريخ اخر زياره.. وهذا يعني أن لكل معلومة ملف Cookie مما يعني أننا سنتعدى العدد المسموح لموقعنا من الـCookies ..!!
لحل هذه المشكله هناك طريقه تعتمد على Name-Value Pairs وتسمى Subkyes المفاتيح الفرعية, هذه الطريقة تمكنك من تخزين أكثر من معلومة واحدة داخل ملف الـ Cookie الواحد والوصول اليها بكل يسر وسهوله .فلو استخدمنا هذه الطريقة في المثال السابق فسوف نجد الـfirstName و lastVisit كشريكين Pairs في ملف Cookie واحد.
تعد هذه الطريقه مفيده لأنه من المفضل ان تضع المعلومات التي لها صلة ببعضها البعض في ملف واحد بالاضافة الى انها تجنبنا الوقوع في أحد محظورات الـCookie وبما أن جميع المعلومات في ملف واحد فهذا يعني أن الـ Attributes تنطبق على جميع المعلومات وعلى سبيل المثال تاريخ الانتهاء فلو وضعنا firstName و lastVisit في ملف واحد وحددنا قيمة الـ Expires بعد ثلاثة أيام فإن كلا من firstName و lastVisit ستكون منتهية في عضون ثلاثة أيام .
ولعمل ذلك أيضا لدينا طريقتين, إما اسناد مباشر للقيم أو استنساخ الـكائن httpCookie
الطريقة الأولى
Response.Cookies(“UserInfo”)(“firstName”)=”Ayman” Response.Cookies(“UserInfo”)(“lastVisit”)=DateTime.Now.ToString Response.Cookies(“UserInfo”).Expires=DateTime.Now.AddDays(1)
الطريقة الثانية
Dim myCookie As New HttpCookie("userInfo")
myCookie.Values("firstName") = "Ayman"
myCookie.Values("lastVisit") = DateTime.Now.ToString
myCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(myCookie)قابلية الرؤية للـCookies
جميع الصفحات الموجوده في تطبيقالويب الذي تنشأه لها القدره على التعامل مع الـ Cookies المنشأة من قبل موقعك, ولكن ماذا اذا أحببت في يوم ما أن تربط Cookie معينة بمجلد معين, أو بنطاق فرعي معين ..!
حسناً,
•ان أحببت أن تحدد قابلية الرؤية لـ Cookie بمجلد معين على الخادم فعليك استخدام الخاصية Path التابعة لكائن الـ Cookie :
Dim myCookie As New HttpCookie("MyCookie")
myCookie.Value = "written " & Now.ToString
myCookie.Expires = Now.AddDays(1)
myCookie.Path = "/myFolder"
Response.Cookies.Add(myCookie)وبالطبع يمكنك اسناد القيم بشكل مباشر كما اسلفنا
Response.Cookies(“MyCookie”).Path=”/myFolder”
الان حاول استخدام الـ Cookie التي قمت بإنشائها من قبل مجلد اخر غير myFolder ستلاحظ بأنك لا تستطيع لأنها أصبحت حكرا على المجلد myFolder .
•إن أحببت أن تحدد قابلية الرؤية لـ Cookie بنطاق أو نطاق فرعي معين Sub-Domain ففي هذه الحالة عليك استخدام الخاصية Domain
Response.Cookies("domain").Value = DateTime.Now.ToString
Response.Cookies("domain").Expires = DateTime.Now.AddDays(1)
Response.Cookies("domain").Domain = "sub1.dev4arabs.com"في هذه الحالة ستكون الـCookie التي اسمها Domain حكرا على جميع الصفحات التي تنتمي للنطاق الفرعي sub1 .
أما اذا أردت ان تجعلها مشتركة بين عدة نطاقات فرعيه فعليك استخدام الكود التالي :
Response.Cookies("domain").Value = DateTime.Now.ToString
Response.Cookies("domain").Expires = DateTime.Now.AddDays(1)
Response.Cookies("domain").Domain = " dev4arabs.com"قراءة الـ Cookies
عندما يتم طلب عنوان ما من المتصفح, فإنه يقوم بتفتيش سريع عن cookies تابعة لهذا العنوان فإن وجد شيئا ارسله الى الخادم Server مع الصفحة المراد عرضها في هذه الحالة يمكنك استخدام الكائن Request لقرائة محتويات هذه الـ Cookies, في الحقيقة اذا نظرنا الى مبدأ الـكائن Request لوجدناه شبيه بالـكائن Response – الذي استخدمناه لكتابة الـCookies منذ قليل- ولكنه يعمل في الاتجاه المعاكس!
لذا يمكنك قراءة الـ Cookies التابعة لموقعك بنفس الاسلوب الذي قمت فيه بكتابتها, المثال التالي والذي يقوم بجلب القيمة الموجوده في الfirstName Cookie ووضعها داخل أداة الـ Label التي تنتمي الى عائلة الـ Server Controls سيوضح لك الصورة :
يمكنك استخدام الكود التالي :
If Not Request.Cookies(“firstName”) Is Nothing Then Label1.Text=Server.HtmlEncode(Reqest.Cookies(“firstName”)) End If ‘وهذا أيضا If Not Request.Cookies(“firstName”) Is Nothing Then Dim myCookie as HttpCookie = Request.Cookies(“firstName”) Label1.Text=Server.HtmlEncode(myCookie.Value) End If
في الكود السابق نلاحظ ما يلي :
•أولا استخدام الشرط IF للتأكد من وجود الـ Cookie. يعتبر التأكد اذا كانت الـ cookie التي نريد العمل عليها موجودة أم لا أمرا مهما, ولذك لأن الاستثناء Exception المنتمي الى الفئة System.NullReferenceException بالمرصاد وينتظر على أحر من الجمر أي خلل في تطبيقك كي يظهر على الشاشه فلو لم تكن الـ Cookie التي نريدها موجوده لأتحت له الفرصة بالظهور وحينها ستنزعج انت والمستخدم!
•ثانيا استخدام الـ Server.HtmlEncode في العرض .
ولكن يا أيمن.. الكود السابق يستخدم اذا كانت الـ Cookie تحتوي على قيمة واحده فقط أي أنها لا تحوي على SubKeys !!
بالفعل كلامك صحيح و اعذرني ان اطلت عليك النقاط, اليك الكود الذي يمكنك من استخلاص القيمة من Cookie تحوي على SubKeys
If Not Request.Cookies(“userInfo”) Is Nothing Then Label1.Text= _ Server.HtmlEncode(Request.Cookies(“UserIfo”)(“firstName”)) Label2.Text _ Server.HtmlEncode(Request.Cookies(“UserInfo”)(“lastVisit”)) End If
نلاحظ في الكود السابق:
•أنت تعلم ان المعلومات تخزن في الـ Cookies على هيئة String لذا فإن قيمة lastVisit ستكون على هيئة String وفي الحقيقة هي عبارة عن تاريخ فإذا أردت أن تستقبل القيمة على هيئة DateTime
Dim lastVisit as DateTime lastVist=CDate(Request.Cookies(“UserInfo”)(“lastVisit”))
بالإضافة الى امكانية استخلاص المعلومات من الـ Cookies يمكنك معرفة بعض المعلومات عن الـ Cookie نفسها كـالخاصيه Domain و Path ولكن للأسف لا يمكنك معرفة تاريخ انتهاء الـ Cookie.
Dim i as Integer Dim Result as String ="" Dim myCookie as httpCookie For i = 0 to Request.Cookies.Count -1 myCookie= Request.Cookies(i) Result &=" Cookie name="& Server.HtmlEncode(myCookie.Name) &"<br>" Result &="Cookie Value =" & Server.HtmlEncode(myCookie.Value) & _ "<br> <br>" Next Label1.Text=Result
عند تشغيل الكود السابق سيسرد لك جميع الـCookies الموجوده والمتاحه لك, بالإضافة الى Cookie تسمى ASP.NET_SessionId وهي Cookie تقوم بانشائها ASP.NET ليختزن فيها بيانات الجلسات Sessions .
تعديل الـ Cookies
ربما ستحتاج في يوم من الأيام الى تعديل Cookie سواء من ناحية قيمتها أو بعض خواصها كتمديد تاريخ الانتهاء مثلاً, حسناً دعني أفسر لك حقيقة كلمة " تعديل الـ Cookies " في الحقيقة يجب أن تعلم أنك لا تستطيع ان تعدل الـ Cookie مباشرة وذلك لأن الـ Cookie التي تريد التعديل عليها لا تزال موجودة في مكان ما على جهاز المستخدم, فالتعديل عليها يقتضي انشاء Cookie جديده تحمل خواص معدله بنفس اسم الـ Cookie التي نود تعديلها ومن ثم ارسالها وكما اسلفنا سابقا اذا حصل تطابق لاسمي ملفين Cookie فان الجديده ستكتب فوق القديمه Overwrite. لذا فنحن نحتاج الى الـكائنين & Response Request أو بالأحرىالخاصية Cookies الموجودة في كل منهما وكما يقال بالمثال يتضح المقال, إليك المثال التالي والذي يقوم بتعديل عدد زيارات المتستخدم المختزنه في Cookie اسمها Counter :
Dim Counter As Integer If Request.Cookies(“counter”) Is Nothing Then Counter=0 Else Counter=CInt(Request.Cookies(“counter”).Value) End If Counter += 1 Response.Cookies(“counter”)=Counter.ToString Response.Cookies(“counter”)=DateTime.Now.AddDays(1)
حذف الـ Cookies
كما لا يمكنك تعديل الـCookie مباشرة لأنها موجوده على جهاز المستخدم فإنه لا يمكنك حذفها مباشرة لنفس السبب, المتصفح هو عالمنا الرئيسي في عملية مسح الـ Cookies, أسلفنا أن تعديل الـ Cookie يقتضي انشاء Cookie جديده بخواص معدله بنفس الاسم. في الحقيقة عملية الحذف تشبهها تماماً أي أنك تحتاج لأنشاء Cookie جديده بنفس الاسم الذي تحمله الـ Cookie المراد حذفها ولكن بتاريخ انتهاء قبل التاريخ الحالي فعندما يجري المتصفح عملية الجرد فسيجد أن تاريخ هذه الCookie قد انتهى فيقوم بحذفها. اليك المثال التالي والذي يقوم بحذف Counter Cookie التي انشأناها قبل قليل:
Response.Cookies(“counter”).Expires=DateTime.Now.AddDays(-1)
عمليتي الحذف والتعديل للـ Subkeys
العملية ذاتها والوصول الى الـ Subkey بنفس الطريقة التي كنت قد استخدمتها للإنشاء
Response.Cookies(“userInfo”)(“lastVisit”).Expires=DateTime.Now.AddDays(1)
الكود السابق كان للتعديل, دعنا الان نناقش أمر الحذف.. لو أردت أن تسند قيمة قبل التاريخ الحالي للـCookie فستحذف الـ Cookie بكاملها لا المفتاح الفرعيSubkey , لذا يجب عليك استخدام الـ Value’s Collection, اليك الكود التالي :
Dim myCookie as HttpCookie= Request.Cookies(“userInfo”) myCookie.Values.Remove(“firstName”) myCookie.Expires=DateTime.Now.AddDays(1) Response.Cookies.Add(myCookie)
خاتمه
لا تكثر من استخدام الـCookies بشكل عشوائي ولكن حاول تنظيمها داخل ملفات و Subkeys حسب الحاجة لها.
لقد كان هذا مقال سريع عن الـ Cookies و كيفية استخدامها في ASP.NET أتمنى ألا أكون قد أطلت عليكم, مع تمنياتي لكم بـ.net سعيده !
منقووووول
اللهم علمنا ما ينفعنا وانفعنا بما علمتنا