جافا سكريبت وملفات تعريف الارتباط

جافا سكريبت وملفات تعريف الارتباط

تشرح هذه المقالة جافا سكريبت وملفات تعريف الارتباط۔

سنشرح كل شيء بعناية خطوة بخطوة، بدءًا من أساسيات ملفات تعريف الارتباط والقراءة والكتابة والأمان إلى الأمثلة العملية۔

YouTube Video

javascript-cookie.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>JavaScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    .container-flex {
 32        display: flex;
 33        flex-wrap: wrap;
 34        gap: 2em;
 35        max-width: 1000px;
 36        margin: 0 auto;
 37        padding: 1em;
 38        background-color: #ffffff;
 39        border: 1px solid #ccc;
 40        border-radius: 10px;
 41        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 42    }
 43
 44    .left-column, .right-column {
 45        flex: 1 1 200px;
 46        min-width: 200px;
 47    }
 48
 49    h1, h2 {
 50        font-size: 1.2rem;
 51        color: #007bff;
 52        margin-top: 0.5em;
 53        margin-bottom: 0.5em;
 54        border-left: 5px solid #007bff;
 55        padding-left: 0.6em;
 56        background-color: #e9f2ff;
 57    }
 58
 59    button {
 60        display: block;
 61        margin: 1em auto;
 62        padding: 0.75em 1.5em;
 63        font-size: 1rem;
 64        background-color: #007bff;
 65        color: white;
 66        border: none;
 67        border-radius: 6px;
 68        cursor: pointer;
 69        transition: background-color 0.3s ease;
 70    }
 71
 72    button:hover {
 73        background-color: #0056b3;
 74    }
 75
 76    #output {
 77        margin-top: 1em;
 78        background-color: #1e1e1e;
 79        color: #0f0;
 80        padding: 1em;
 81        border-radius: 8px;
 82        min-height: 200px;
 83        font-family: Consolas, monospace;
 84        font-size: 0.95rem;
 85        overflow-y: auto;
 86        white-space: pre-wrap;
 87    }
 88
 89    .highlight {
 90        outline: 3px solid #ffc107; /* yellow border */
 91        background-color: #fff8e1;  /* soft yellow background */
 92        transition: background-color 0.3s ease, outline 0.3s ease;
 93    }
 94
 95    .active {
 96        background-color: #28a745; /* green background */
 97        color: #fff;
 98        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 99        transition: background-color 0.3s ease, box-shadow 0.3s ease;
100    }
101  </style>
102</head>
103<body>
104    <div class="container">
105        <h1>JavaScript Console</h1>
106        <button id="executeBtn">Execute</button>
107        <div id="output"></div>
108    </div>
109
110    <script>
111        // Override console.log to display messages in the #output element
112        (function () {
113            // Override console.log
114            const originalLog = console.log;
115            console.log = function (...args) {
116                originalLog.apply(console, args);
117                const message = document.createElement('div');
118                message.textContent = args.map(String).join(' ');
119                output.appendChild(message);
120            };
121
122            // Override console.error
123            const originalError = console.error;
124            console.error = function (...args) {
125                originalError.apply(console, args);
126                const message = document.createElement('div');
127                message.textContent = args.map(String).join(' ');
128                message.style.color = 'red'; // Color error messages red
129                output.appendChild(message);
130            };
131        })();
132
133        document.getElementById('executeBtn').addEventListener('click', () => {
134            // Prevent multiple loads
135            if (document.getElementById('externalScript')) return;
136
137            const script = document.createElement('script');
138            script.src = 'javascript-cookie.js';
139            script.id = 'externalScript';
140            //script.onload = () => console.log('javascript-cookie.js loaded and executed.');
141            //script.onerror = () => console.log('Failed to load javascript-cookie.js.');
142            document.body.appendChild(script);
143        });
144    </script>
145</body>
146</html>

جافا سكريبت وملفات تعريف الارتباط

ملف تعريف الارتباط يشير إلى قطع صغيرة من البيانات مخزنة في متصفح المستخدم۔ تُستخدم بشكل أساسي للأغراض التالية:۔

  • مصادقة المستخدم (الحفاظ على حالة تسجيل الدخول)
  • حفظ إعدادات المستخدم (اللغة، السمة، إلخ)
  • التتبع (سجل التصفح، إلخ)

في جافا سكريبت، يمكنك قراءة وكتابة ملفات تعريف الارتباط باستخدام document.cookie۔

إنشاء (كتابة) ملفات تعريف الارتباط

تُنشأ ملفات تعريف الارتباط باستخدام الصيغة التالية:۔

1document.cookie = "username=JohnDoe";
  • هذا الكود يحفظ ملف تعريف الارتباط باسم "username=JohnDoe" في المتصفح۔

إنشاء ملفات تعريف الارتباط بتاريخ انتهاء صلاحية

يمكن تحديد تاريخ انتهاء صلاحية لملفات تعريف الارتباط۔ إذا لم يتم تحديد تاريخ انتهاء صلاحية، يُعامل كـ ملف تعريف ارتباط للجلسة ويتم حذفه عند إغلاق المتصفح۔

1const date = new Date();
2date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000)); // 7 days
3const cookieText = "username=JohnDoe; expires=" + date.toUTCString() + "; path=/; SameSite=None; Secure"
4document.cookie = cookieText;
5console.log(`Cookie Text  : ${cookieText}`);
6console.log(`Cookie Value : ${document.cookie}`);
  • تحدد السمة expires تاريخ انتهاء صلاحية ملف تعريف الارتباط بتنسيق UTC۔
  • تحدد السمة path المسار الذي سيتم إرسال ملف تعريف الارتباط إليه۔ / تعني الموقع بأكمله۔
  • إذا حددت SameSite=None، سيتم إرسال الـCookie حتى مع الطلبات عبر المواقع المختلفة۔ ومع ذلك، في هذه الحالة يجب دائمًا تضمين خاصية Secure۔
  • تحديد خاصية Secure يجعل الـCookie يقتصر على الاتصالات عبر HTTPS فقط، مما يعزز الأمان۔
  • من خلال الرجوع إلى document.cookie، يمكنك الحصول على جميع الـCookies المتاحة في الصفحة الحالية كسلسلة نصية۔
  • باستخدام console.log، يمكنك التحقق من الفرق بين قيم الـCookie الفعلية المضبوطة في المتصفح والقيم التي يمكن استرجاعها۔

الحصول على (قراءة) ملفات تعريف الارتباط

يمكنك استرجاع جميع ملفات تعريف الارتباط كسلسلة نصية باستخدام document.cookie۔

1const date = new Date();
2date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000)); // 7 days
3document.cookie = "theme=dark; expires=" + date.toUTCString() + "; path=/; SameSite=None; Secure"
4
5console.log(document.cookie);
6// Output: "username=JohnDoe; theme=dark"
  • قيمة الإرجاع لـ document.cookie هي سلسلة واحدة مجمّعة تحتوي جميع الـCookies بصيغة 'key=value;
  • من الملائم استخدام دالة لتحليل هذه السلسلة واستخراج القيمة المطلوبة۔

دالة للحصول على قيمة ملف تعريف الارتباط

 1function getCookie(name) {
 2    const cookies = document.cookie.split('; ');
 3    for (const cookie of cookies) {
 4        const [key, value] = cookie.split('=');
 5        if (key === name) {
 6            return decodeURIComponent(value);
 7        }
 8    }
 9    return null;
10}
11
12console.log(getCookie("username")); // "JohnDoe"
  • تقوم هذه الدالة بتقسيم المفاتيح والقيم باستخدام split() وتعيد القيمة إذا تطابق المفتاح المحدد۔
  • باستخدام decodeURIComponent، يمكنك استرداد الأحرف المشفرة بشكل صحيح۔
  • إذا لم يكن المفتاح المقابل موجودًا، تعيد الدالة القيمة null۔

حذف ملفات تعريف الارتباط

يمكن حذف ملف تعريف الارتباط عن طريق تعيين تاريخ انتهائه إلى تاريخ في الماضي۔

1document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=None; Secure";
2
3console.log(document.cookie);
4// Output: "theme=dark"
  • من خلال تعيين قيمة فارغة لـ username وتعيين تاريخ انتهاء الصلاحية في الماضي، سيتم حذفها۔
  • عند حذف الـCookie، يجب أيضًا مطابقة خصائص path وSameSite وSecure مع تلك التي استخدمت عند إنشائها۔
  • في هذا المثال، يتم حذف username وتبقى الـCookies الأخرى مثل theme=dark۔

خيارات ملفات تعريف الارتباط

يمكنك تحديد خيارات متنوعة للتحكم في سلوك ملف تعريف الارتباط۔ أهمها كالتالي:۔

تحدد تاريخ انتهاء صلاحية ملف تعريف الارتباط بتنسيق UTC۔ إذا لم يتم تحديده، يصبح ملف تعريف الارتباط خاصًا بالجلسة ويُحذف عند إغلاق المتصفح۔

تحدد تاريخ انتهاء صلاحية ملف تعريف الارتباط بالثواني۔ لها الأولوية على `expires`۔

تحدد المسار الذي سيتم إرسال ملف تعريف الارتباط من أجله۔ على سبيل المثال، إذا حددت `/admin`، سيتم إرسال ملف تعريف الارتباط فقط إلى الصفحات تحت هذا المسار۔

تحدد النطاق الذي يكون فيه ملف تعريف الارتباط صالحًا۔ عادةً ما يتم تعيينه للنطاق الحالي، ولكن يمكنك تطبيقه على جميع النطاقات الفرعية مثل `.example.com`۔

عند تحديد هذه السمة، يُرسل ملف تعريف الارتباط فقط عبر HTTPS۔ لزيادة الأمان، قم دائمًا بتعيين هذه السمة للمعلومات الحساسة۔

تتحكم فيما إذا كانت ملفات تعريف الارتباط تُرسل في الطلبات بين المواقع۔ يمكنك تحديد واحدة من القيم الثلاث التالية:۔

- `Strict`
    يتم إرسال ملفات تعريف الارتباط فقط للطلبات من نفس الموقع۔

- `Lax`
    يتم إرسال ملفات تعريف الارتباط للتصفح العادي، ولكن مع بعض القيود۔

- `None`
    يمكن إرسال ملفات تعريف الارتباط حتى في الطلبات بين المواقع۔ ومع ذلك، يلزم أيضًا وجود السمة `Secure`۔

مثال: ملف تعريف ارتباط آمن

1document.cookie = "sessionId=abc123; secure; SameSite=Strict";
  • إذا حددت خاصية secure، سيتم إرسال الـCookie فقط عبر اتصالات HTTPS۔
  • إذا حددت SameSite=Strict، لن يتم إرسال الـCookie مع الطلبات بين المواقع، مما يجعله فعالًا كإجراء مضاد لهجمات CSRF۔
  • هذه الخصائص الآمنة ضرورية للـCookies المهمة المستخدمة للمصادقة أو إدارة الجلسات۔

الترميز وفك الترميز

نظرًا لأن قيم ملفات تعريف الارتباط قد تحتوي على أحرف خاصة، فمن الأكثر أمانًا استخدام encodeURIComponent۔

1const date = new Date();
2date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000)); // 7 days
3
4const username = "JohnDoe";
5document.cookie =
6    "username=" + encodeURIComponent(username) +
7    "; max-age=604800; path=/; SameSite=None; Secure";
8
9console.log(decodeURIComponent(getCookie("username"))); // "JohnDoe"
  • باستخدام encodeURIComponent، يمكنك تخزين المسافات والرموز وغيرها في الـCookie بشكل آمن۔
  • عند قراءتها، استخدم decodeURIComponent لاستعادة النص الأصلي۔
  • في هذا المثال، تم استخدام max-age=604800 لتعيين فترة انتهاء الصلاحية إلى 7 أيام (604,800 ثانية)۔ هذه طريقة لتحديد تاريخ انتهاء الصلاحية، مشابهة لطريقة expires۔ يمكن تحديد خاصية max-age بالثواني وغالبًا ما تكون أسهل في الاستخدام۔

مثال عملي: حفظ وتحميل السمة

فيما يلي مثال على حفظ السمة التي يختارها المستخدم في ملف تعريف ارتباط وتطبيقها تلقائيًا عند الزيارة التالية۔

 1function setTheme(theme) {
 2    document.cookie =
 3        "theme=" + encodeURIComponent(theme) +
 4        "; max-age=604800; path=/; SameSite=None; Secure"; // 1 week
 5    applyTheme(theme);
 6}
 7
 8function applyTheme(theme) {
 9    document.body.style.backgroundColor = theme === "dark" ? "#333" : "#fff";
10    document.body.style.color = theme === "dark" ? "#fff" : "#000";
11}
12
13function getCookie(name) {
14    const cookies = document.cookie.split('; ');
15    for (const cookie of cookies) {
16        const [key, value] = cookie.split('=');
17        if (key === name) {
18            return decodeURIComponent(value);
19        }
20    }
21    return null;
22}
23
24const savedTheme = getCookie("theme");
25if (savedTheme) {
26    applyTheme(savedTheme);
27}
1<button onclick="setTheme('light')">Light</button>
2<button onclick="setTheme('dark')">Dark</button>
  • دالة setTheme تحفظ النمط المختار في الـCookie وتستدعي applyTheme فورًا لتحديث الشاشة۔
  • وظيفة applyTheme تغير خلفية وألوان نص الـbody وفقًا للنمط۔
  • في هذا المثال، نظرًا لأن max-age=604800 محددة، يتم الاحتفاظ بإعداد النمط لمدة أسبوع۔
  • نظرًا لإمكانية الاحتفاظ باختيار المستخدم عند إعادة زيارة الصفحة، يتم تحسين تجربة المستخدم (UX)۔

قيود وتحذيرات ملفات تعريف الارتباط

كن على علم بالنقاط التالية عند استخدام ملفات تعريف الارتباط:۔

  • قيود الحجم حجم ملف تعريف الارتباط الواحد محدود بحوالي 4 كيلوبايت۔

  • حد على عدد ملفات تعريف الارتباط التي يمكن حفظها اعتمادًا على المتصفح، يمكنك فقط حفظ حوالي 20 إلى 50 لكل نطاق۔

  • احتياطات الأمان يتم حفظ محتوى الـCookies أساسًا كنص عادي، لذا فهي ليست مناسبة لتخزين المعلومات السرية مثل كلمات المرور۔

  • كوكيز غير قابلة للوصول من جافاسكريبت كوكيز التي تحتوي على خاصية HttpOnly لا يمكن قراءتها من جافاسكريبت لأسباب أمنية۔

الخادم وملفات الـCookies

1Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict

بعض سمات ملفات الكوكي، مثل HttpOnly، لا يمكن تعيينها باستخدام جافاسكريبت۔ يجب تعيين هذه السمات من جانب الخادم۔

الملخص

التعامل مع الكوكيز من خلال جافاسكريبت يمكن أن يعزز تجربة المستخدم ويحافظ على الحالة۔ مع ذلك، يرجى الانتباه للنقاط التالية لمعالجتها بأمان وبطريقة مناسبة۔

  • خزن فقط الحد الأدنى من المعلومات الضرورية من منظور الخصوصية والأمان، تجنب تخزين المعلومات الشخصية أو الحساسة وقم بتسجيل البيانات الضرورية فقط۔

  • عين سمات الأمان بشكل صحيح قم بتعيين سمات مثل Secure وSameSite لمنع الهجمات عبر المواقع مثل XSS وCSRF۔

  • تشفير وفك تشفير البيانات استخدم encodeURIComponent وdecodeURIComponent لتخزين وقراءة قيم الكوكيz بأمان ليتم التعامل بشكل صحيح مع الأحرف الخاصة واليابانية۔

من خلال تعلم الطريقة الصحيحة لاستخدام الكوكيز، يمكنك بناء تطبيقات ويب أكثر تطورًا وأمانًا۔

يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔

YouTube Video