مشاركة الموارد المتعدّدة المصادر (CORS)

مشاركة الموارد المتعدّدة المصادر بأمان

Mariko Kosaka

تحظر سياسة المصدر نفسه في المتصفِّح قراءة مورد من مصدر مختلف. تمنع هذه الآلية المواقع الإلكترونية الضارة من قراءة بيانات المواقع الإلكترونية الأخرى، ولكنها تمنع أيضًا الاستخدامات المشروعة.

تحتاج تطبيقات الويب الحديثة غالبًا إلى الحصول على موارد من مصدر مختلف، مثل استرداد بيانات JSON من نطاق مختلف أو تحميل صور من موقع إلكتروني آخر إلى عنصر <canvas>. ويمكن أن تكون هذه موارد عامة يجب أن تكون متاحة لأي شخص لقراءتها، لكن سياسة المصدر نفسه تحظر استخدامها. في السابق، استخدم المطوِّرون حلولاً بديلة، مثل JSONP.

تعمل ميزة مشاركة الموارد المتعدّدة المصادر (CORS) على حلّ هذه المشكلة بطريقة موحّدة. يتيح تفعيل CORS للخادم إمكانية إعلام المتصفّح بأنّه يمكنه استخدام مصدر إضافي.

كيف يعمل طلب الموارد على الويب؟

الطلب والاستجابة
صورة توضيحية لطلب العميل واستجابة الخادم.

يمكن للمتصفح والخادم تبادل البيانات عبر الشبكة باستخدام بروتوكول نقل الروابط النصية (HTTP). يحدد HTTP قواعد الاتصال بين مقدم الطلب والمجيب، بما في ذلك المعلومات اللازمة للحصول على مورد.

يتفاوض عنوان HTTP تبادل الرسائل بين العميل والخادم، ويتم استخدامه لتحديد إمكانية الوصول. يتم تقسيم كل من طلب المتصفّح ورسالة استجابة الخادم إلى رأس ونص.

معلومات حول الرسالة، مثل نوعها أو ترميزها. يمكن أن يتضمّن العنوان مجموعة متنوعة من المعلومات التي يتم التعبير عنها في صورة أزواج المفتاح/القيمة. يحتوي عنوان الطلب وعنوان الاستجابة على معلومات مختلفة.

نموذج عنوان الطلب

Accept: text/html
Cookie: Version=1

يعادل هذا العنوان قول "أريد تلقي HTML ردًا على ذلك. ها هي كعكة الكوكيز لديّ".

نموذج عنوان للاستجابة

Content-Encoding: gzip
Cache-Control: no-store

يعادل هذا العنوان قول "البيانات في هذه الاستجابة مرمَّزة باستخدام gzip. لا تخزن هذا الجهاز في ذاكرة التخزين المؤقت".

النص الأساسي

الرسالة نفسها يمكن أن يكون هذا النص عاديًا أو صورة ثنائية أو JSON أو HTML أو العديد من التنسيقات الأخرى.

كيف تعمل سياسة CORS؟

تطلب سياسة المصدر نفسه من المتصفِّح حظر الطلبات من مصادر متعددة. عندما تحتاج إلى مورد عام من مصدر مختلف، فإن خادم توفير الموارد يخبر المتصفح أن المصدر الذي يرسل الطلب يمكنه الوصول إلى مورده. يتذكر المتصفح ذلك ويسمح بمشاركة الموارد من مصادر متعددة لهذا المورد.

الخطوة 1: طلب العميل (المتصفح)

عندما يُجري المتصفِّح طلبًا من مصادر متعددة، يضيف المتصفّح عنوان Origin بالأصل الحالي (المخطط والمضيف والمنفذ).

الخطوة 2: استجابة الخادم

عندما يرى أحد الخوادم هذا العنوان ويريد السماح بالوصول إليه، يضيف عنوان Access-Control-Allow-Origin إلى الاستجابة التي تحدّد المصدر المتقدّم (أو * للسماح بأي مصدر).

الخطوة 3: تلقّي المتصفّح ردًّا

وعندما يرى المتصفِّح هذه الاستجابة باستخدام عنوان Access-Control-Allow-Origin مناسب، يشارك بيانات الاستجابة مع موقع العميل.

مشاركة بيانات الاعتماد مع سياسة مشاركة الموارد المتعددة المصادر (CORS)

لأسباب تتعلق بالخصوصية، يتم استخدام بروتوكول CORS عادةً للطلبات المجهولة المصدر، التي لا يتم تحديد مقدم الطلب فيها. إذا كنت تريد إرسال ملفات تعريف الارتباط عند استخدام CORS، التي يمكنها تحديد المرسِل، عليك إضافة عناوين إضافية إلى الطلب والاستجابة.

الطلب

أضِف credentials: 'include' إلى خيارات الجلب كما في المثال التالي. ويشمل ذلك ملف تعريف الارتباط مع الطلب على النحو التالي:

fetch('https://example.com', {
  mode: 'cors',
  credentials: 'include'
})

الإجابة

يجب ضبط Access-Control-Allow-Origin على مصدر محدّد (بدون استخدام حرف بدل باستخدام *)، كما يجب ضبط Access-Control-Allow-Credentials على true.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

طلبات التنفيذ الأوّلي لاستدعاءات HTTP المركّبة

عندما يُجري تطبيق ويب طلب HTTP معقدًا، يضيف المتصفح طلبًا مبدئيًا في بداية سلسلة الطلب.

تحدّد مواصفات CORS طلبًا معقدًا على النحو التالي:

  • طلب يستخدم طرقًا أخرى غير GET أو POST أو head.
  • طلب يتضمن عناوين غير Accept أو Accept-Language أو Content-Language.
  • طلب يحتوي على عنوان Content-Type بخلاف application/x-www-form-urlencoded أو multipart/form-data أو text/plain.

تنشئ المتصفحات تلقائيًا أي طلبات مسبقة لازمة وترسلها قبل رسالة الطلب الفعلية. الطلب المبدئي هو طلب OPTIONS، مثل المثال التالي:

OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE

من جهة الخادم، يستجيب التطبيق الذي يتلقى الطلب لطلب مبدئي يتضمن معلومات حول الطرق التي يقبلها التطبيق من هذا المصدر:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

يمكن أن تتضمّن استجابة الخادم أيضًا عنوان Access-Control-Max-Age لتحديد المدة بالثواني لتخزين نتائج الطلب المُسبَق. ويتيح ذلك للعميل إرسال عدة طلبات معقدة بدون الحاجة إلى تكرار طلب ما قبل التنفيذ.