it-swarm.asia

كيفية إصلاح خطأ getImageData () لقد تلوثت اللوحة القماشية ببيانات الأصل المتداخل؟

تعمل الكود الخاص بي بشكل جيد للغاية على مضيف بلدي ولكنه لا يعمل على الموقع.

لقد حصلت على هذا الخطأ من وحدة التحكم ، لهذا السطر .getImageData(x,y,1,1).data:

Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-Origin data. 

جزء من الكود:

jQuery.Event.prototype.rgb=function(){
        var x =  this.offsetX || (this.pageX - $(this.target).offset().left),y =  this.offsetY || (this.pageY - $(this.target).offset().top);
        if (this.target.nodeName!=="CANVAS")return null;
        return this.target.getContext('2d').getImageData(x,y,1,1).data;
    }

ملاحظة: عنوان URL الخاص بالصورة (src) هو من عنوان url للنطاق الفرعي

103
Erfan Safarpoor

كما قال الآخرون إنك "تلوث" اللوحة من خلال التحميل من مجال أصول متقاطعة.

https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image

ومع ذلك ، قد تكون قادرًا على منع ذلك من خلال الإعداد ببساطة:

img.crossOrigin = "Anonymous";

يعمل هذا فقط إذا قام الخادم البعيد بتعيين العنوان التالي بشكل مناسب:

Access-Control-Allow-Origin "*"

اختيار ملف Dropbox عند استخدام خيار "الرابط المباشر" هو مثال رائع على ذلك. يمكنني استخدامه على oddprints.com لتحريك الصور من رابط صورة صندوق الإسقاط عن بُعد ، إلى لوحة الرسم الخاصة بي ، ثم إرسال بيانات الصورة مرة أخرى إلى الخادم الخاص بي. كل ما في جافا سكريبت

85
matt burns

لقد وجدت أنه كان علي استخدام .setAttribute('crossOrigin', '') واضطررت إلى إلحاق طابع زمني بسلسلة استعلام عنوان URL لتجنب استجابة 304 تفتقر إلى رأس Access-Control-Allow-Origin.

هذا يعطيني

var url = 'http://lorempixel.com/g/400/200/';
var imgObj = new Image();
imgObj.src = url + '?' + new Date().getTime();
imgObj.setAttribute('crossOrigin', '');
34
Kirby

لن تتمكن من رسم الصور مباشرة من خادم آخر في لوحة قماشية ثم استخدام getImageData. إنها مشكلة أمنية وسيتم اعتبار اللوحة "ملوثة".

هل من الأفضل لك حفظ نسخة من الصورة على الخادم الخاص بك باستخدام PHP ثم تحميل الصورة الجديدة فقط؟ على سبيل المثال ، يمكنك إرسال عنوان URL إلى البرنامج النصي PHP وحفظه على الخادم الخاص بك ، ثم إعادة اسم الملف الجديد إلى javascript كما يلي:

<?php //The name of this file in this example is imgdata.php

  $url=$_GET['url'];
  $img = file_get_contents($url);
  $fn = substr(strrchr($url, "/"), 1);
  file_put_contents($fn,$img);
  echo $fn;

?>

يمكنك استخدام البرنامج النصي PHP مع بعض javascript مثل هذا:

xi=new XMLHttpRequest();
xi.open("GET","imgdata.php?url="+yourImageURL,true);
xi.send();

xi.onreadystatechange=function() {
  if(xi.readyState==4 && xi.status==200) {
    img=new Image;
    img.onload=function(){ 
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    }
    img.src=xi.responseText;
  }
}

إذا كنت تستخدم getImageData على اللوحة بعد ذلك ، فستعمل بشكل جيد.

بدلاً من ذلك ، إذا كنت لا تريد حفظ الصورة بأكملها ، فيمكنك تمرير إحداثيات x & y إلى البرنامج النصي PHP وحساب قيمة rgba بالبكسل في هذا الجانب. أعتقد أن هناك مكتبات جيدة للقيام بهذا النوع من معالجة الصور في PHP.

إذا كنت تريد استخدام هذا النهج ، فأعلمني إذا كنت بحاجة إلى مساعدة في تنفيذه.

تحرير: أشارت اللمحات إلى أن البرنامج النصي php مكشوف ويسمح للإنترنت باستخدامه بشكل ضار. هناك مليون طريقة للتعامل مع هذا ، واحدة من أبسط كونه نوعًا من التشويش على عناوين URL ... أعتقد أن ممارسات php الآمنة تستحق google منفصل ؛ P

17
jaya

كنت أرى هذا الخطأ على Chrome أثناء اختبار الرمز الخاص بي محليًا. لقد قمت بالتبديل إلى Firefox وأنا لا أرى الخطأ بعد الآن. ربما التبديل إلى متصفح آخر هو حل سريع.

إذا كنت تستخدم الحل الوارد في الإجابة الأولى ، فتأكد من إضافة img.crossOrigin = "Anonymous"; بعد إعلان المتغير img (على سبيل المثال ، var img = new Image();).

2
Safwan

أنت "تلوث" قماش من خلال التحميل من مجال أصول مشتركة. تحقق من هذه المادة MDN:

https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image

2
srquinn

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

2
axelduch

كما يقول matt burns في إجابته ، قد تحتاج إلى تمكين CORS على الخادم حيث يتم استضافة الصور ذات المشاكل.

إذا كان الخادم هو Apache ، فيمكن القيام بذلك عن طريق إضافة المقتطف التالي (من هنا ) إلى تهيئة VirtualHost أو ملف .htaccess:

<IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
        <FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
            SetEnvIf Origin ":" IS_CORS
            Header set Access-Control-Allow-Origin "*" env=IS_CORS
        </FilesMatch>
    </IfModule>
</IfModule>

... إذا قمت بإضافته إلى VirtualHost ، فربما تحتاج إلى إعادة تحميل تهيئة Apache أيضًا (على سبيل المثال. Sudo service Apache2 reload إذا كان Apache يعمل على خادم Linux)

0
Nick F

كنت أواجه نفس المشكلة ، وعملت بالنسبة لي ببساطة عن طريق تسلسل https:${image.getAttribute('src')}

0
Livia Rett

عند العمل على المحلية إضافة خادم

كان لدي مشكلة مماثلة عند العمل على المحلية. سيكون عنوان url هو المسار إلى الملف المحلي ، على سبيل المثال ملف: ///Users/PeterP/Desktop/folder/index.html.

يرجى ملاحظة أنني على MAC.

حصلت على هذه الجولة عن طريق تثبيت خادم HTTP على مستوى العالم. https://www.npmjs.com/package/http-server

خطوات:

  1. التثبيت الشامل: npm install http-server -g
  2. تشغيل الخادم: http-server ~/Desktop/folder/

ملاحظة: أفترض أن لديك عقدة مثبتة ، وإلا فلن تحصل على أوامر npm قيد التشغيل.

0
Anas