يسمح للمتصفح بإصدار طلبات XMLHttpRequest لخوادم التوليف ، وبالتالي التغلب على القيد الذي لا يمكن استخدام AJAX إلا في نفس الأصل.
تقدم هذه المقالة الآلية الداخلية للكورس بالتفصيل.
(وصف الصورة: تم التقاطه في Oasis Park في العين ، الإمارات)
1. مقدمة
يتطلب CORs كلا من المتصفح والخادم. حاليًا ، تدعم جميع المتصفحات هذه الوظيفة ، ولا يمكن أن يكون متصفح IE أقل من IE10.
يتم إكمال عملية اتصال CORS بأكملها تلقائيًا بواسطة المتصفح ولا تتطلب مشاركة المستخدم. بالنسبة للمطورين ، لا يختلف اتصال CORS عن نفس الأصل Ajax Communication ، والرمز هو نفسه تمامًا. بمجرد أن يكتشف المتصفح أن Ajax يطلب الأصل المتقاطع ، فإنه سيضيف تلقائيًا بعض معلومات الرأس الإضافية ، وأحيانًا سيكون هناك طلب إضافي ، لكن المستخدم لن يشعر به.
لذلك ، فإن مفتاح تنفيذ اتصال CORS هو الخادم. طالما أن الخادم ينفذ واجهة CORS ، يمكن تنفيذ الاتصالات عبر الأصل.
طلبان
يقسم المتصفح طلبات CORS إلى فئتين: طلب بسيط وطلب غير بسيط.
طالما تم استيفاء الشرطين الرئيسيين التاليين في نفس الوقت ، فهو طلب بسيط.
(1) طريقة الطلب هي إحدى الطرق الثلاث التالية:
hedgetpost
(2) لا تتجاوز معلومات رأس HTTP الحقول التالية:
exceptaccept-languageContent-languagelast-event-idcontent-type: يقتصر فقط على ثلاثة قيم application/x-www-form-urlencoded ، multipart/form-data ، text/plain
أي شخص لا يفي بالشرطين أعلاه في نفس الوقت هو طلب غير بسيط.
إن معالجة المتصفح مع هذين الطلبين مختلفان.
3. طلب بسيط 3.1 العملية الأساسية
للحصول على الطلبات البسيطة ، يصدر المتصفح مباشرة CORS. على وجه التحديد ، أضف حقل Origin إلى معلومات الرأس.
فيما يلي مثال. وجد المتصفح أن طلب AJAX عبر الأصل كان طلبًا بسيطًا ، وقد أضاف تلقائيًا حقل Origin إلى معلومات الرأس.
GET /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
في معلومات الرأس أعلاه ، يتم استخدام حقل Origin للإشارة إلى المصدر (Protocol + Domain Name + Port) يأتي الطلب. بناءً على هذه القيمة ، يقرر الخادم ما إذا كان سيوافق على الطلب.
إذا لم يكن المصدر المحدد حسب Origin ضمن نطاق الإذن ، فسيقوم الخادم بإرجاع استجابة HTTP العادية. وجد المتصفح أن معلومات الرأس عن هذه الاستجابة لم تحتوي على حقل Access-Control-Allow-Origin (انظر أدناه للحصول على التفاصيل) ، لذلك كان من المعروف أن هناك خطأ ، وبالتالي تم طرح خطأ ، تم التقاطه بواسطة وظيفة اتصال onerror لـ XMLHttpRequest . لاحظ أنه لا يمكن تحديد هذا الخطأ بواسطة رمز الحالة ، لأن رمز الحالة لاستجابة HTTP قد يكون 200.
إذا كان اسم المجال المحدد بواسطة Origin ضمن نطاق الإذن ، فستكون للاستجابة التي يتم إرجاعها بواسطة الخادم العديد من حقول الرأس الإضافية.
Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Credentials: trueAccess-Control-Expose-Headers: FooBarContent-Type: text/html; charset=utf-8
من بين معلومات الرأس أعلاه ، هناك ثلاثة حقول تتعلق بطلبات CORS ، وكلها تبدأ Access-Control- .
(1) الوصول إلى السيطرة على الأصول
هذه الخانة مطلوبه. قيمتها هي إما قيمة حقل Origin في وقت الطلب ، أو * ، مما يشير إلى أن طلب أي اسم مجال مقبول.
(2) الوصول إلى السيطرة-السموم
هذا الحقل اختياري. قيمتها هي قيمة منطقية تشير إلى ما إذا كنت تريد إرسال ملفات تعريف الارتباط. بشكل افتراضي ، لا يتم تضمين ملفات تعريف الارتباط في طلبات CORS. ضبط على true ، مما يعني أن الخادم يسمح له صراحة. يمكن تضمين ملفات تعريف الارتباط في الطلب وإرسالها إلى الخادم معًا. لا يمكن ضبط هذه القيمة إلا على true . إذا لم يرسل الخادم ملفات تعريف الارتباط بواسطة المتصفح ، فاحذف الحقل.
(3) من رؤساء السيطرة على السيطرة
هذا الحقل اختياري. عندما تطلب CORS ، يمكن أن تحصل طريقة getResponseHeader() لكائن XMLHttpRequest فقط على 6 حقول أساسية: Cache-Control ، Content-Language ، Content-Type ، Expires ، Last-Modified ، Pragma . إذا كنت ترغب في الحصول على حقول أخرى ، فيجب عليك تحديدها في Access-Control-Expose-Headers . يحدد المثال أعلاه أن getResponseHeader('FooBar') يمكن أن يعيد قيمة حقل FooBar .
3.2 مع السمة
كما ذكر أعلاه ، لا ترسل طلبات CORS ملفات تعريف الارتباط ومعلومات مصادقة HTTP بشكل افتراضي. إذا كنت ترغب في إرسال ملفات تعريف الارتباط إلى الخادم ، فمن ناحية ، فأنت بحاجة إلى الخادم للاتفاق وتحديد حقل Access-Control-Allow-Credentials .
Access-Control-Allow-Credentials: true من ناحية أخرى ، يجب على المطور فتح خاصية withCredentials في طلب AJAX.
var xhr = new XMLHttpRequest();xhr.withCredentials = true;خلاف ذلك ، لن يرسل المتصفح حتى إذا وافق الخادم على إرسال ملفات تعريف الارتباط. بدلاً من ذلك ، يتطلب الخادم ضبط ملفات تعريف الارتباط ، ولن يتعامل المتصفح.
ومع ذلك ، إذا تم حذف الإعدادات withCredentials ، فسيظل بعض المتصفحات ترسل ملفات تعريف الارتباط معًا. في هذا الوقت ، يمكنك أن تغلق بشكل صريح withCredentials .
xhr.withCredentials = false; تجدر الإشارة إلى أنه إذا كنت ترغب في إرسال ملفات تعريف الارتباط ، فلا يمكن تعيين Access-Control-Allow-Origin كخط ATERISK ، ويجب عليك تحديد اسم مجال صريح يتوافق مع صفحة الويب المطلوبة. في الوقت نفسه ، لا تزال ملفات تعريف الارتباط تتبع سياسة الأصل من نفس. سيتم تحميل ملفات تعريف الارتباط فقط مع أسماء مجال الخادم. لن يتم تحميل ملفات تعريف الارتباط من أسماء النطاقات الأخرى ، ولا يمكن document.cookie صفحة الويب في رمز الويب الأصلي (المتقاطع الأصلي) قراءة ملفات تعريف الارتباط تحت اسم مجال الخادم.
4. طلب غير بسيط 4.1 طلب ما قبل الرحلة
طلب غير بسيط هو طلب يحتوي على متطلبات خاصة للخادم ، مثل طريقة PUT أو DELETE ، أو Content-Type هو application/json .
سيؤدي طلب CORS الذي ليس طلبًا بسيطًا إلى إضافة طلب استعلام HTTP قبل الاتصال الرسمي ، والذي يسمى طلب "Prevlight".
يسأل المستعرض أولاً الخادم ما إذا كان اسم المجال الذي يوجد فيه صفحة الويب الحالية موجودًا على قائمة ترخيص الخادم ، والتي يمكن استخدام أفعال HTTP وحقول الرأس. فقط عند استلام الرد الإيجابي ، هل سيصدر المتصفح طلب XMLHttpRequest رسميًا ، وإلا سيتم الإبلاغ عن خطأ.
فيما يلي برنامج نصي JavaScript للمتصفح.
var url = 'http://api.alice.com/cors';var xhr = new XMLHttpRequest();xhr.open('PUT', url, true);xhr.setRequestHeader('X-Custom-Header', 'value');xhr.send();
في الكود أعلاه ، يتم PUT طريقة طلب HTTP وإرسال معلومات رأس مخصصة X-Custom-Header .
وجد المتصفح أن هذا كان طلبًا غير بسيط ، لذلك أصدر تلقائيًا طلب "قبل الرحلة" ، ويتطلب من الخادم تأكيد ذلك يمكن طلب ذلك. فيما يلي معلومات رأس HTTP لطلب "المبدئي" هذا.
OPTIONS /cors HTTP/1.1Origin: http://api.bob.comAccess-Control-Request-Method: PUTAccess-Control-Request-Headers: X-Custom-HeaderHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0... طريقة الطلب المستخدمة من قبل طلب "Preflight" هي OPTIONS ، مما يشير إلى استخدام هذا الطلب للاستفسار. في معلومات الرأس ، يكون الحقل الرئيسي هو Origin ، مما يشير إلى المصدر الذي يأتي منه الطلب.
بالإضافة إلى حقل Origin ، تتضمن معلومات الرأس الخاصة بطلب "Preflight" حقلتين خاصتين.
(1) الوصول إلى المترجمة
مطلوب هذا الحقل لسرد أساليب HTTP التي سيتم استخدامها لطلب CORS للمتصفح. PUT المثال أعلاه.
(2) وصول وصول المراقبة
هذا الحقل عبارة عن سلسلة مفصولة بفاصلة تحدد حقل معلومات الرأس الإضافي الذي سيتم إرسال طلب CORS للمتصفح. المثال أعلاه هو X-Custom-Header .
4.2 الاستجابة لطلبات ما قبل الرحلة
بعد أن يتلقى الخادم طلب "Preflight" ، بعد التحقق من Origin ، تؤكد حقول Access-Control-Request-Method Control و Access-Control-Request-Headers ، على أن الطلبات المتقاطعة مسموح بها ، ويمكنك الرد.
HTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:15:39 GMTServer: Apache/2.0.61 (Unix)Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderContent-Type: text/html; charset=utf-8Content-Encoding: gzipContent-Length: 0Keep-Alive: timeout=2, max=100Connection: Keep-AliveContent-Type: text/plain
في استجابة HTTP أعلاه ، يكون المفتاح هو حقل Access-Control-Allow-Origin ، مما يعني أنه يمكن http://api.bob.com طلب البيانات. يمكن أيضًا ضبط هذا الحقل على علامة النجمة للموافقة على أي طلب مضاعف.
Access-Control-Allow-Origin: *
إذا كان المتصفح ينكر طلب "المبدئي" ، فسيتم إرجاع استجابة HTTP العادية ، ولكن لا توجد حقول للرأس ذات الصلة بـ CORS. في هذا الوقت ، سيحدد المتصفح أن الخادم لا يوافق على طلب Preflight ، لذلك يتم تشغيل الخطأ والتقاطه بواسطة وظيفة رد الاتصال onerror لكائن XMLHttpRequest . ستقوم وحدة التحكم بطباعة رسالة الخطأ التالية.
XMLHttpRequest cannot load http://api.alice.com.Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
الحقول الأخرى المتعلقة بالكرات التي يستجيب لها الخادم كما يلي.
Access-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000(1) أساليب الوصول إلى السيطرة
هذا الحقل مطلوب ، وقيمته عبارة عن سلسلة مفصولة بفاصلة تشير إلى جميع طرق طلب المجال المتقاطع التي يدعمها الخادم. لاحظ أنه يتم إرجاع جميع الأساليب المدعومة ، وليس فقط الطريقة التي يطلبها المتصفح. هذا لتجنب طلبات "Preflight" المتعددة.
(2) وصول وصول الرصاص
إذا كان طلب المتصفح يتضمن حقل Access-Control-Request-Headers Access-Control-Allow-Headers . إنها أيضًا سلسلة مفصولة فاصلة تشير إلى أن جميع حقول الرأس التي يدعمها الخادم لا تقتصر على الحقول التي يطلبها المتصفح في "Prectlight".
(3) الوصول إلى السيطرة-السموم
هذا الحقل له نفس المعنى الذي هو عليه عند الطلب بطريقة بسيطة.
(4) Access-Control-Max-age
هذا الحقل اختياري ويستخدم لتحديد فترة صحة طلب المبدئي هذا ، في ثوان. في النتائج المذكورة أعلاه ، تبلغ فترة الصلاحية 20 يومًا (1728،000 ثانية) ، مما يعني أن الاستجابة مخزنة مؤقتًا لمدة 1728،000 ثانية (أي 20 يومًا). خلال هذه الفترة ، لا يلزم أي طلب بريش آخر.
4.3 الطلبات والردود العادية من المتصفح
بمجرد أن يمر الخادم بطلب "Preflight" ، في كل مرة يكون طلب CORS العادي للمتصفح هو نفسه طلب بسيط ، سيكون هناك حقل معلومات رأس Origin . سيكون استجابة الخادم أيضًا حقل رأس Access-Control-Allow-Origin .
فيما يلي طلب CORS العادي للمتصفح بعد طلب "Preflight".
PUT /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comX-Custom-Header: valueAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
تتم إضافة حقل Origin لمعلومات الرأس أعلاه تلقائيًا بواسطة المتصفح.
فيما يلي الاستجابة العادية من الخادم.
Access-Control-Allow-Origin: http://api.bob.comContent-Type: text/html; charset=utf-8
في معلومات الرأس أعلاه ، يجب تضمين حقل Access-Control-Allow-Origin في كل استجابة.
5. مقارنة مع JSONP
يتم استخدام CORS في نفس الغرض من JSONP ، لكنه أقوى من JSONP.
يدعم JSONP فقط GET الطلبات ، يدعم CORS جميع أنواع طلبات HTTP. تتمثل ميزة JSONP في أنها تدعم المتصفحات القديمة ويمكنها طلب بيانات من مواقع الويب التي لا تدعم CORS.
(زيادة)