بشكل عام، سيكون لدى الفرق اسم مجال خاص لوضع الموارد الثابتة، على سبيل المثال، Tencent هو gtimg.com، أو Baidu هو bdimg.com أو تستخدم العديد من الفرق خدمات Tencent Cloud أو Alibaba Cloud.
غالبًا ما تختلف أسماء النطاقات للصفحات الرئيسية. عندما يكون من الضروري إجراء عمليات getImageData() أو toDataURL() على صور القماش، تنشأ مشكلات عبر المجالات، وهناك أكثر من مستوى واحد من المشكلات عبر المجالات.
أولاً، في الخطوة الأولى، يحتاج خادم الصور إلى تكوين معلومات Access-Control-Allow-Origin، على سبيل المثال:
على سبيل المثال، تضيف PHP معلومات رأس الاستجابة، ويشير حرف البدل * إلى أن أي اسم نطاق مسموح به:
header(Access-Control-Allow-Origin: *);
أو حدد اسم المجال:
header(Access-Control-Allow-Origin: www.zhangxinxu.com);
في هذه المرحلة، لن يحتوي متصفح Chrome بعد الآن على رسائل خطأ متعلقة بـ Access-Control-Allow-Origin، ولكن ستكون هناك رسائل خطأ أخرى عبر النطاقات.
2. مشكلة getImageData عبر النطاقات في صورة القماشبالنسبة للصور عبر النطاقات، طالما أنه يمكن عرضها بشكل طبيعي على صفحة الويب، فيمكن رسمها باستخدام واجهة برمجة تطبيقات drawImage() الخاصة بالقماش. ولكن إذا كنت تريد المضي قدمًا والحصول على معلومات البكسل الكاملة للصورة من خلال طريقة getImageData()، فمن المحتمل أن ترتكب خطأً.
على سبيل المثال، استخدم الكود التالي للحصول على معلومات الصورة الرمزية الخاصة بك على جيثب:
var Canvas = document.createElement('canvas');var context = Canvas.getContext('2d');var img = new Image();img.onload = function () { context.drawImage(this, 0, 0) ; context.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
والنتيجة هي الخطأ التالي المعروض ضمن متصفح Chrome:
لم يتم اكتشاف DOMException: فشل في تنفيذ 'getImageData' على 'CanvasRenderingContext2D': اللوحة القماشية ملوثة ببيانات مشتركة الأصل.
خطأ متصفح فايرفوكس هو:
خطأ أمني: العملية غير آمنة.
إذا تم استخدام الأسلوب Canvas.toDataURL()، فسوف يُبلغ عن:
فشل تنفيذ 'toDataURL' على 'HTMLCanvasElement': قد لا يتم تصدير اللوحة القماشية الملوثة
الأسباب هي نفسها في الواقع، بسبب تقاطع المجالات.
فهل هناك أي طريقة لحل هذه المشكلة؟
يمكنك تجربة السمة crossOrigin.
3. تعمل سمة HTML crossOrigin على حل مشكلة الموارد عبر النطاقاتفي HTML5، توفر بعض العناصر سمات تدعم CORS (مشاركة الموارد عبر الأصل) (مشاركة الموارد عبر الأصل)، وتشمل هذه العناصر <img>، و<video>، و<script>، وما إلى ذلك، واسم السمة المقدم هو سمة crossOrigin.
لذلك، يمكن التعامل مع المشكلة عبر النطاقات المذكورة أعلاه على النحو التالي:
var Canvas = document.createElement('canvas');var context = Canvas.getContext('2d');var img = new Image();img.crossOrigin = '';img.onload = function () { context.drawImage (هذا، 0، 0)؛ context.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
ما عليك سوى إضافة img.crossOrigin = ''. على الرغم من أن كود JS هنا يعين سلسلة فارغة، إلا أن قيمة السمة الفعلية التي تعمل تكون مجهولة.
يمكن أن يحتوي crossOrigin على القيمتين التاليتين:
الكلمات الرئيسية | تعريف |
---|---|
مجهول | لا تتطلب طلبات الموارد عبر الأصل للعناصر تعيين علامة بيانات الاعتماد. |
استخدام بيانات الاعتماد | تتطلب طلبات الموارد عبر المجال للعناصر تعيين علامة بيانات الاعتماد، مما يعني أن بيانات الاعتماد مطلوبة للطلب. |
من بينها، طالما أن قيمة سمة crossOrigin ليست بيانات اعتماد استخدام، فسيتم تحليل كل شيء على أنه مجهول، بما في ذلك السلاسل الفارغة، بما في ذلك الأحرف مثل "abc".
على سبيل المثال:
img.crossOrigin = 'abc';console.log(img.crossOrigin); // النتيجة "مجهول";
شيء آخر يجب ملاحظته هو أنه على الرغم من عدم وجود سمة crossOrigin، فإن تعيين crossOrigin=use-credentials سيبلغ عن خطأ عبر المجال افتراضيًا، إلا أن هناك اختلافًا كبيرًا بين الاثنين.
التوافق عبر الأصلتدعم متصفحات IE11+ (IE Edge) وSafari وChrome وFirefox هذه الميزة، وستقوم IE9 وIE10 بالإبلاغ عن خطأ أمني، كما هو موضح في لقطة الشاشة أدناه:
4. لماذا يمكن للسمة crossOrigin حل مشكلة الموارد عبر النطاقات؟crossOrigin=anonymous بدلاً من إخبار الخادم الآخر، لا تحتاج إلى إحضار أي معلومات غير مجهولة المصدر. على سبيل المثال، ملفات تعريف الارتباط، لذلك فإن المتصفح الحالي آمن بالتأكيد.
يبدو الأمر كما لو كنت تريد الذهاب إلى منزل شخص ما لالتقاط قطعة من الملابس. يختلف crossOrigin=anonymous عن إخبار الشخص الآخر أنني أريد الملابس فقط ولا شيء آخر. إذا لم تخبرهم، فقد يضع الطرف الآخر جهاز تنصت أو شيء ما في ملابسهم، وهو ما سيكون غير آمن وسيقوم المتصفح بحظره.
5. ماذا علي أن أفعل إذا كان متصفح IE10 لا يدعم crossOrigin؟عندما نطلب صورًا، فإننا لا نستخدم new Image() مباشرةً، ولكننا نستخدم ajax وطريقة URL.createObjectURL() لحفظ البلد.
الرمز هو كما يلي:
var xhr = new XMLHttpRequest();xhr.onload = function () { var url = URL.createObjectURL(this.response); var img = new Image(); img.onload = function () { // عند هذه النقطة يمكنك استخدام اللوحة القماشية للقيام بكل ما تريد باستخدام رمز img // ... ... // تذكر تحرير الذاكرة بعد استخدام الصورة URL.revocObjectURL(url) }; = url;};xhr.open('GET', url, true);xhr.responseType = 'blob';xhr.send();
هذه الطريقة ليست مناسبة فقط لمتصفح IE10، ولكنها مدعومة أيضًا من قبل جميع المتصفحات التي كانت تدعم crossOrigin في الأصل.
لا يتطلب الأمر سوى طلب أياكس آخر، وهو أمر جيد!
وفقًا للممارسة، في متصفح IE، إذا كانت الصورة المطلوبة كبيرة جدًا، بضعة آلاف من وحدات البكسل، فسيفشل تحميل الصورة، وأعتقد أنها تتجاوز الحد الأقصى لحجم النقطة.
6. الاستنتاجلقد تعلمت القليل من الخبرة في العمل مؤخرًا، وآمل أن يساعد الأصدقاء الذين يواجهون مشكلات مماثلة. آمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.