ما هو النطاق المتقاطع؟
المفهوم: طالما أن هناك أي اختلاف في البروتوكول أو اسم المجال أو المنفذ ، فإنه يعتبر مجالًا مختلفًا.
نسخة الكود كما يلي:
يشير عنوان URL إلى ما إذا كان التواصل مسموحًا به
http://www.a.com/a.js
http://www.a.com/b.js المسموح به تحت نفس اسم المجال
http://www.a.com/lab/a.js
http://www.a.com/script/b.js مجلدات مختلفة تحت نفس اسم المجال
http://www.a.com:8000/A.JS
http://www.a.com/b.js نفس اسم المجال ، لا يُسمح بالمنافذ المختلفة
http://www.a.com/a.js
https://www.a.com/b.js نفس اسم المجال ، لا تسمح بروتوكولات مختلفة
http://www.a.com/a.js
http://70.32.92.74/b.js اسم المجال واسم المجال غير مسموح به IP
http://www.a.com/a.js
http://script.a.com/b.js المجال الرئيسي هو نفسه ، لكن النطاق الفرعي غير مسموح به
http://www.a.com/a.js
http://a.com/b.js نفس اسم المجال ، أسماء المجال الثانوية المختلفة (كما هو موضح أعلاه) غير مسموح بها (لا يوجد وصول إلى ملفات تعريف الارتباط في هذه الحالة)
http://www.cnblogs.com/a.js
http://www.a.com/b.js أسماء المجال المختلفة غير مسموح بها
لا يمكن حل الفرق بين المنافذ والبروتوكولات إلا من خلال الخلفية.
مشاركة الموارد عبر المجال (CORS)
تحدد مشاركة موارد CROS (مشاركة الموارد عبر الأصل) كيفية التواصل المتصفح والخادم عند الوصول إلى موارد المجال المتقاطع. تتمثل الفكرة الأساسية وراء CROS في استخدام رأس HTTP مخصص للسماح للمتصفح بالتواصل مع الخادم ، وبالتالي تحديد ما إذا كان يجب أن يكون الطلب أو الاستجابة ناجحًا أم فشل.
نسخة الكود كما يلي:
<script type = "text/javaScript">
var xhr = new xmlhttprequest () ؛
XHR.Open ("get" ، "/trigkit4" ، true) ؛
xhr.send () ؛
</script>
Trigkit4 أعلاه هو مسار نسبي. إذا أردنا استخدام CORS ، فقد يبدو رمز Ajax ذي الصلة هكذا:
نسخة الكود كما يلي:
<script type = "text/javaScript">
var xhr = new xmlhttprequest () ؛
XHR.Open ("get" ، "http://segmentfault.com/u/trigkit4/"،true) ؛
xhr.send () ؛
</script>
الفرق بين الكود والمرء السابق هو أن المسار النسبي يتم استبداله بالمسار المطلق للمجالات الأخرى ، أي عنوان الواجهة الذي تريد الوصول إليه عبر المجالات.
يتم تحقيق دعم من جانب الخادم لـ CORS بشكل أساسي عن طريق تعيين الوصول إلى السيطرة على الأصل. إذا اكتشف المتصفح الإعدادات المقابلة ، فيمكن السماح لـ Ajax بالوصول عبر المجالات.
لحل مشاكل المجال المتقاطع ، يمكننا استخدام الطرق التالية:
النطاق عبر JSONP
الآن السؤال هو؟ ما هو JSONP؟ تعريف Wikipedia هو: JSONP (JSON مع الحشو) هو "وضع استخدام" لتنسيق البيانات JSON ، والذي يسمح لصفحات الويب بطلب المعلومات من المجالات الأخرى.
يسمى JSONP أيضا Fill-in JSON. إنها طريقة جديدة لتطبيق JSON ، لكنها مجرد JSON مدرجة في مكالمات الوظائف ، على سبيل المثال:
نسخة الكود كما يلي:
Callback ({"name" ، "trigkit4"}) ؛
يتكون JSONP من جزأين: وظيفة رد الاتصال والبيانات. وظيفة رد الاتصال هي وظيفة يجب استدعاؤها على الصفحة عند وصول الاستجابة ، والبيانات هي بيانات JSON التي تم تمريرها في وظيفة رد الاتصال.
في JS ، لا يمكن طلب بيانات مباشرة على مجالات مختلفة باستخدام XMLHTTPrequest. ومع ذلك ، لا بأس في تقديم ملفات البرنامج النصي JS على مجالات مختلفة على الصفحة ، ويستخدم JSONP هذه الميزة لتحقيقها. على سبيل المثال:
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة dosomething (jsondata) {
// معالجة بيانات JSON التي تم الحصول عليها
}
</script>
<script src = "http://example.com/data.php؟callback=dosomething"> </script>
بعد تحميل ملف JS بنجاح ، سيتم تنفيذ الوظيفة التي حددناها في معلمة عنوان URL ، وسيتم تمرير بيانات JSON التي نحتاجها كمعلمات. لذلك ، يتطلب JSONP صفحة من جانب الخادم للتعاون وفقًا لذلك.
نسخة الكود كما يلي:
<؟ PHP
$ callback = $ _get ['callback'] ؛ // احصل على اسم وظيفة رد الاتصال
$ data = array ('a' ، 'b' ، 'c') ؛ // البيانات المراد إرجاعها
صدى الاتصال $. "('. json_encode ($ data).') '؛
؟>
أخيرًا ، الإخراج هو: dosomething (['a' ، 'b' ، 'c']) ؛
إذا كانت صفحتك تستخدم jQuery ، فيمكن استخدام طريقة التغليف لتنفيذ عمليات JSONP بشكل مريح للغاية.
نسخة الكود كما يلي:
<script type = "text/javaScript">
$ .getjson ('http://example.com/data.php؟callback=؟،function (jsondata)') {
// معالجة بيانات JSON التي تم الحصول عليها
}) ؛
</script>
ستقوم jQuery تلقائيًا بإنشاء وظيفة عالمية لاستبدال علامة الاستفهام في رد الاتصال =؟ ، ثم ستدمر البيانات تلقائيًا بعد الحصول عليها. في الواقع ، فإنه يلعب دور وظيفة وكيل مؤقت. ستحدد طريقة $ .getjson تلقائيًا ما إذا كانت المجال المتقاطع. إذا لم يكن المجال المتقاطع ، فسوف يطلق على طريقة Ajax العادية ؛ إذا كان المجال المتقاطع ، فسوف يتصل بوظيفة رد الاتصال JSONP في شكل تحميل غير متزامن لملفات JS.
إيجابيات وسلبيات JSONP
مزايا JSONP هي: لا يتم تقييدها بواسطة سياسات متماثلة مثل طلب AJAX الذي تم تنفيذه بواسطة كائن XMLHTTPREQUEST ؛ يتمتع بتوافق أفضل ويمكن تشغيله في المتصفحات القديمة ، دون دعم XMLHTTPrequest أو ActiveX ؛ وبعد اكتمال الطلب ، يمكن إرجاع النتيجة عن طريق الاتصال بالاستدعاء.
عيب JSONP هو أنه يدعم فقط الحصول على طلبات وليس أنواع أخرى من طلبات HTTP مثل Post ؛ إنه يدعم فقط طلبات HTTP للمجال ، ولا يمكنها حل مشكلة كيفية إجراء مكالمات JavaScript بين صفحتين في مجالات مختلفة.
مقارنة بين CROS و JSONP
بالمقارنة مع JSONP ، فإن CORS هو بلا شك أكثر تقدماً ومريحة وموثوقية.
1. يمكن لـ JSONP تنفيذ الطلبات فقط ، بينما يدعم CORS جميع أنواع طلبات HTTP.
2. باستخدام CORS ، يمكن للمطورين استخدام XMLHTTPRequest العادي لبدء الطلبات والحصول على البيانات ، التي لديها معالجة خطأ أفضل من JSONP.
3. JSONP مدعوم بشكل أساسي من قبل المتصفحات القديمة. غالبًا ما لا يدعمون الكورس ، ومعظم المتصفحات الحديثة تدعم بالفعل كورز).
المتقاطع عبر تعديل الوثيقة
تتمتع المتصفحات بسياسة متماثلة ، وأحد قيودها هو أنه في الطريقة الأولى قلنا أنه لا يمكن طلب المستندات من مصادر مختلفة من خلال طريقة AJAX. القيد الثاني هو أنه لا يمكن تنفيذ تفاعل JS بين أطر عمل مختلف المجالات في المتصفح.
يمكن للأطر المختلفة الحصول على كائنات نافذة ، لكنها لا تستطيع الحصول على خصائص وطرق مقابلة. على سبيل المثال ، هناك صفحة مع عنوان http://www.example.com/a.html. هناك iframe في هذه الصفحة ، و src هو http://example.com/b.html. من الواضح أن هذه الصفحة لديها مجال مختلف من إطار IFRAME بداخله ، لذلك لا يمكننا الحصول على الأشياء في IFRAME عن طريق كتابة رمز JS في الصفحة:
نسخة الكود كما يلي:
<script type = "text/javaScript">
اختبار الوظيفة () {
var iframe = document.getElementById ('ifame') ؛
var win = document.contentWindow ؛ // يمكنك الحصول على كائن النافذة في iframe ، لكن خصائص وطرق كائن النافذة غير متوفرة تقريبًا
var doc = win.document ؛ // لا يمكن الحصول على كائن المستند في iframe هنا
var name = win.name ؛ // لا يمكن الحصول على سمة اسم كائن النافذة هنا
}
</script>
<iframe id = "iframe" src = "http://example.com/b.html" onload = "test ()"> </frame>
في هذا الوقت ، يمكن أن يكون Document.domain مفيدًا. نحتاج فقط إلى تعيين مستند. نومان من كلتا الصفحتين: http://www.example.com/a.html و http://example.com/B.html إلى نفس اسم المجال. ولكن تجدر الإشارة إلى أن إعداد المستند. PODOMAIN محدود. لا يمكننا فقط تعيين المستند. Pommain إلى مجال الوالدين أو العالي ، ويجب أن يكون المجال الرئيسي هو نفسه.
1. تعيين المستند .دوين في الصفحة http://www.example.com/a.html:
نسخة الكود كما يلي:
<iframe id = "iframe" src = "http://example.com/b.html" onload = "test ()"> </frame>
<script type = "text/javaScript">
document.domain = 'example.com' ؛ // تعيين كمجال رئيسي
اختبار الوظيفة () {
ALERT (document.getElementByID ('iframe'). contentWindow) ؛ // contentWindow يمكن الحصول على كائن نافذة نافذة الطفل
}
</script>
2. قم أيضًا بتعيين document.domain في الصفحة http://example.com/b.html:
نسخة الكود كما يلي:
<script type = "text/javaScript">
document.domain = 'example.com' ؛
</script>
طريقة تعديل المستند. Pommain مناسبة فقط للتفاعلات بين الأطر مع نطاقات فرعية مختلفة.