GetImageData () त्रुटि को ठीक कैसे करें कैनवास को क्रॉस-ऑरिजनल डेटा द्वारा दागी गई है?


131

मेरा कोड मेरे लोकलहोस्ट पर बहुत अच्छा काम कर रहा है लेकिन यह साइट पर काम नहीं कर रहा है।

मुझे कंसोल से यह त्रुटि मिली, इस पंक्ति के लिए .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 से है


8
मुझे यह त्रुटि तब भी हो रही है जब img.src एक स्थानीय रिश्तेदार url है: "img / foo.png" - तो इस बारे में क्रॉस-ऑरिजिन क्या है?
सैनफोर्ड स्टैब

Stackoverflow.com/a/16218015/5175433 देखें : "क्रोम एक ही डोमेन से अलग-अलग स्थानीय फ़ाइलों को खट्टा नहीं मानता है।"
a_P

जवाबों:


116

जैसा कि दूसरों ने कहा है कि आप क्रॉस ऑरिजिन डोमेन से लोड करके कैनवास को "टेनिंग" कर रहे हैं।

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

हालाँकि, आप इसे केवल सेटिंग द्वारा रोकने में सक्षम हो सकते हैं:

img.crossOrigin = "Anonymous";

यह केवल तभी काम करता है जब रिमोट सर्वर निम्नलिखित हेडर को उचित रूप से सेट करता है:

Access-Control-Allow-Origin "*"

ड्रॉपबॉक्स फ़ाइल चयनकर्ता जब "सीधा लिंक" विकल्प का उपयोग इस का एक बड़ा उदाहरण है। मैं इसका उपयोग करता है oddprints.com पर , दूरस्थ ड्रॉपबॉक्स छवि url से छवियों को अपने कैनवास में उतारने के लिए, और फिर छवि डेटा को अपने सर्वर में वापस जमा करूं। सभी जावास्क्रिप्ट में


1
इस त्रुटि को ठीक करने के लिए काम किया जब jsfiddle.net में एक imgur छवि लोड हो रहा है
ट्रैविस जे

3
मेरे लिए काम किया है, तो मैं पहले तो सेट स्रोत और फिर crossorigin डाल पहुँच डेटा ऑनलोड
jones

2
क्या होगा अगर यह एक स्थानीय फ़ाइल है, और आपका ऐप इंटरनेट का उपयोग नहीं करता है? एंड्रॉइड वेबव्यू ऐप की तरह और छवि HTML फ़ाइल के समान फ़ोल्डर में है। यह इसे हल नहीं करता है।
कर्टिस

44

मैंने पाया कि मुझे हेडर की .setAttribute('crossOrigin', '')कमी के कारण 304 प्रतिक्रिया से बचने के लिए URL के क्वेरी स्ट्रिंग के लिए टाइमस्टैम्प का उपयोग करना था 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', '');

3
एक स्थानीय फ़ाइल पर सर्वर के बिना यह कोशिश करना: 'फ़ाइल में छवि पर पहुंच: /// C: /..//g/colorPaletteCtrl.png; 1507058959277' मूल 'null' को CORS नीति से अवरोधित किया गया है: अमान्य प्रतिक्रिया । उत्पत्ति 'अशक्त' इसलिए पहुंच की अनुमति नहीं है।
1930 में सैनफोर्ड स्टैब ऑक्ट

1
बस imgObj.setAttribute('crossOrigin', '')यह मेरे लिए हल का उपयोग कर - धन्यवाद! img.crossOrigin = "Anonymous"साथ ही काम करता है (जैसा कि यहां बताया गया है )। @SanfordStaab ब्राउजर स्थानीय फ़ाइलों को एक अलग डोमेन पर होने के कारण मानते हैं, अन्यथा वेबसाइट के मालिक आपकी स्थानीय फ़ाइलों को पढ़ सकते हैं। आपको उसी डोमेन से छवियों का अनुरोध करने की आवश्यकता है, या आपके अनुरोध की प्रतिक्रिया में हेडर को उस ब्राउज़र को बताने की आवश्यकता है जो उस फ़ाइल को पढ़ने के लिए अन्य डोमेन से कोड के लिए ठीक है।

19

आप एक कैनवास में सीधे दूसरे सर्वर से चित्र नहीं बना पाएंगे और फिर उपयोग कर पाएंगे getImageData। यह एक सुरक्षा मुद्दा है और कैनवास को "दागी" माना जाएगा।

क्या यह आपके लिए काम करेगा कि आप PHP का उपयोग करके छवि की एक प्रति अपने सर्वर में सहेज लें और फिर नई छवि लोड करें? उदाहरण के लिए, आप URL को PHP स्क्रिप्ट में भेज सकते हैं और इसे अपने सर्वर पर सहेज सकते हैं, फिर इस तरह अपनी जावास्क्रिप्ट में नया फ़ाइल नाम लौटाएँ:

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

  $url=$_GET['url'];

  // prevent hackers from uploading PHP scripts and pwning your system
  if(!@is_array(getimagesize($url))){
    echo "path/to/placeholderImage.png";
    exit("wrong file type.");
  }

  $img = file_get_contents($url);

  $fn = substr(strrchr($url, "/"), 1);
  file_put_contents($fn,$img);
  echo $fn;

?>

आप इस तरह से कुछ अजाक्स जावास्क्रिप्ट के साथ PHP स्क्रिप्ट का उपयोग करेंगे:

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उसके बाद कैनवास पर उपयोग करते हैं, तो यह ठीक काम करेगा।

वैकल्पिक रूप से, यदि आप पूरी छवि को सहेजना नहीं चाहते हैं, तो आप अपनी PHP स्क्रिप्ट में x & y निर्देशांक पास कर सकते हैं और उस तरफ पिक्सेल के आरजीबीए मूल्य की गणना कर सकते हैं। मुझे लगता है कि PHP में उस तरह की इमेज प्रोसेसिंग करने के लिए अच्छी लाइब्रेरी हैं।

यदि आप इस दृष्टिकोण का उपयोग करना चाहते हैं, तो मुझे बताएं कि क्या आपको इसे लागू करने में सहायता की आवश्यकता है।

edit-1: peeps ने बताया कि php स्क्रिप्ट उजागर है और इंटरनेट को संभावित रूप से दुर्भावनापूर्ण रूप से उपयोग करने की अनुमति देता है। इसे संभालने के लिए एक लाख तरीके हैं, जिनमें से एक सबसे सरल URL ऑब्फ़्सकेशन के कुछ प्रकार है ... मैं रेकॉर्ड सुरक्षित php प्रथाओं एक अलग गूगल के लायक है? पी

संपादन -2: लोकप्रिय मांग के अनुसार, मैंने यह सुनिश्चित करने के लिए एक चेक जोड़ा है कि यह एक छवि है और php स्क्रिप्ट नहीं (से: PHP चेक अगर फ़ाइल एक छवि है )।


15
इसके अलावा - स्थानीय फ़ाइल सिस्टम से छवि और स्क्रिप्ट को लोड करना, एक ही समस्या बनाता है।
गाइ डैफनी

2
यह बहुत सुरक्षित नहीं है कि कोई व्यक्ति आपके सर्वर को बड़ी फ़ाइलों के साथ बाढ़ कर सकता है जो php स्क्रिप्ट का उपयोग करके खराब होगा
LAX1DUDE

1
@ LAX1DUDE का उत्तर एक साधारण सुरक्षा जांच के साथ बेहतर हुआ
जंपजैक

1
इस विधि के लिए धन्यवाद यह भी संभव है कि किसी छवि को tesseract.js OCR इंजन को बिना नोड का उपयोग किए पास किया जाए। js (बस कॉल को Tgeract.recognize (img) में img.onload () फ़ंक्शन में जोड़ें।
जंपजैक

1
आपने उपयोगकर्ताओं द्वारा प्रदान किए गए अपलोड के फ़ाइल नाम, फ़ाइल / माइम प्रकार, स्थान और आकार को मान्य करने की आवश्यकता है। यह कोड कई हमलों के लिए असुरक्षित है। मैं इसे पाठक के लिए एक अभ्यास के रूप में छोड़ दूंगा, लेकिन मुझे विश्वास है कि इस कोड के साथ वेबसर्वर की जड़ में .php फ़ाइलों को अपलोड करना संभव है।
हिबर्न 8

4

मैं इस त्रुटि को देख रहा था Chromeजबकि मैं अपने कोड का स्थानीय स्तर पर परीक्षण कर रहा था। मैंने स्विच किया Firefoxऔर मुझे कोई त्रुटि दिखाई नहीं दे रही है। हो सकता है कि दूसरे ब्राउजर में स्विच करना जल्दी ठीक हो जाए।

यदि आप पहले उत्तर में दिए गए हल का उपयोग कर रहे हैं, तो सुनिश्चित करें कि आप चर (उदाहरण के लिए ) img.crossOrigin = "Anonymous";घोषित करने के ठीक बाद जोड़ देंगे ।imgvar img = new Image();


2

आपकी समस्या यह है कि आप बाहरी छवि लोड करते हैं, जिसका अर्थ है किसी अन्य डोमेन से। यह सुरक्षा त्रुटि का कारण बनता है जब आप अपने कैनवास संदर्भ के किसी भी डेटा तक पहुंचने का प्रयास करते हैं।


हां, मुझे अपलोड उपडोमेन से छवि मिलती है ... मैं क्या करूँ?
इरफान सफ़रपुर

1
वैसे आप अपनी छवि को पुनः प्राप्त करने के लिए एक प्रॉक्सी का उपयोग कर सकते हैं, यह प्रॉक्सी उसी डोमेन पर होगी जिस पर आप अपना कैनवास चला रहे हैं।
अक्सादेलुच

1
मैं अपने कंप्यूटर से नई छवि अपलोड कर रहा हूं और इसे कैनवास में लोड करने का प्रयास कर रहा हूं और मुझे यह त्रुटि मिल रही है। मैं किसी भी प्रकार की सर्वर छवि का उपयोग नहीं कर रहा हूं।
पीयूष ढोलरिया

आपके कंप्यूटर को सर्वर द्वारा देखा जाता है जहां स्क्रिप्ट स्थित है (लेकिन निष्पादित नहीं) बाहरी डोमेन के रूप में, जैसा कि कैनवास में कॉपी की गई छवि आपके कंप्यूटर पर बनाई गई है, जहां स्क्रिप्ट वास्तव में निष्पादित होती है।
जंपजैक

2

आप एक क्रॉस ओरिजिन डोमेन से लोड करके कैनवास को "टेनिंग" कर रहे हैं। इस MDN लेख को देखें:

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


मैंने जोड़ा <ifModule mod_setenvif.c> <ifModule mod_headers.c> <fileschatch "\ _ (cur। gif | ico | jpe; g | png | svgz? | webp] $"> SetEnvIf उत्पत्ति ":" IS_CORS हैडर ने Access- नियंत्रण-अनुमति-उत्पत्ति "*" env = IS_CORS </ FilesMatch> </ ifModule> </ ifModule> सभी डोमेन को सुरक्षित करने के लिए लेकिन काम नहीं!
इरफान सफ़रपुर

1
आप किस ब्राउज़र में परीक्षण कर रहे हैं? और सुनिश्चित करें कि आपने अपाचे को फिर से शुरू किया है।
क्रम

मैं अपाचे को पुनः आरंभ नहीं कर सकता ... मेरे पास cpanel खाता है।
इरफान सफ़रपुर

2
आप अपने अपाचे सेटअप को कॉन्फ़िगर करने में मदद नहीं कर सकते, क्षमा करें। इस सवाल के दायरे से बाहर भी। अपाचे सेटअप के बारे में अपनी परेशानियों को एक नए प्रश्न पर पोस्ट करें और समुदाय आपको वहां मदद करने में प्रसन्न होगा।
क्रिकिन

1

स्थानीय काम करते समय एक सर्वर जोड़ें

स्थानीय स्तर पर काम करते समय मेरे पास एक समान मुद्दा था। आप यूआरएल स्थानीय फ़ाइल जैसे फ़ाइल के लिए पथ होने जा रहा है: ///Users/PeterP/Desktop/folder/index.html।

कृपया ध्यान दें कि मैं एक मैक पर हूं।

मैंने इसे विश्व स्तर पर http-server स्थापित करके प्राप्त किया। https://www.npmjs.com/package/http-server

कदम:

  1. वैश्विक स्थापित: npm install http-server -g
  2. सर्वर चलाएं: http-server ~/Desktop/folder/

पुनश्च: मुझे लगता है कि आपने नोड स्थापित किया है, अन्यथा आप बहुत दूर तक चलने वाले एनपीएम कमांड प्राप्त नहीं करेंगे।


0

जैसा कि मैट बर्न्स अपने जवाब में कहते हैं , आपको सर्वर पर कोर्स को सक्षम करने की आवश्यकता हो सकती है जहां समस्या छवियों की मेजबानी की जाती है।

यदि सर्वर अपाचे है, तो यह निम्नलिखित स्निपेट ( यहां से ) को जोड़कर या तो आपके वर्चुअलोस्ट कॉन्फिगर या .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 लिनक्स सर्वर पर चल रहा है)


0

मेरी समस्या इतनी गड़बड़ थी कि मैंने यह सुनिश्चित करने के लिए कि किसी भी कोर मुद्दों नहीं हो सकता है बस बेस 64 छवि को इनकोड किया


-2

मैं आज उसी समस्या को पूरा करता हूं, और इसे कोड द्वारा हल करता हूं।

HTML कोड:

<div style='display: none'>
  <img id='img' src='img/iak.png' width='600' height='400' />
</div>
<canvas id='iak'>broswer don't support canvas</canvas>

जेएस कोड:

var canvas = document.getElementById('iak')
var iakImg = document.getElementById('img')
var ctx = canvas.getContext('2d')
var image = new Image()
image.src=iakImg.src
image.onload = function () {
   ctx.drawImage(image,0,0)
   var data = ctx.getImageData(0,0,600,400)
}

ऊपर की तरह कोड, और कोई क्रॉस-डोमेन समस्या नहीं है।


1
Src मूल्य अभी भी एक क्रॉस ओरिजिनल सोर्स है तो यह समस्या से कैसे बचता है?
लवेन दयल

फ़ाइल जैसे स्थानीय HTML फ़ाइल (कोई सर्वर) चलाते समय यह तरीका काम करता है: /// X: /htmlfile.html। अधिकांश लोग अपने बयानों को ";" के साथ समाप्त करते हैं। "Var data = .." कथन का क्या मतलब है? मुझे ऐसा क्यों लगता है कि यह "क्रॉस-डोमेन" त्रुटि से बचा जाता है। लेकिन यह करता है, धन्यवाद।
dcromley

डबल स्मार्ट कार्री
मारी सेलवन

1
@dcromley "अधिकांश लोग अपने बयानों को समाप्त करते हैं?" मानकों के अनुसार अर्धविराम का उपयोग करने की अनुशंसा नहीं की जाती है। अर्धविराम बस अधिक काम जोड़ते हैं, बदसूरत दिखते हैं, और कोड उनके बिना पूरी तरह से काम करता है। चेक github.com/standard/standard
madprops

1
@madprops developer.mozilla.org का कहना है कि "जावास्क्रिप्ट अनुप्रयोगों में एक उपयुक्त वाक्यविन्यास के साथ बयान होते हैं। एक एकल कथन में कई पंक्तियाँ हो सकती हैं। यदि प्रत्येक कथन एक अर्धविराम द्वारा अलग किया गया है, तो एक पंक्ति में कई कथन हो सकते हैं। यह एक कीवर्ड नहीं है। , लेकिन कीवर्ड का एक समूह। " तो मैं "हमेशा उपयोग" गुट में हूँ। मैं यह भी नहीं जानता था कि एक "कभी नहीं" गुट था। मुझे लगता है कि बाद वाला भी मानता है कि पृथ्वी सपाट है? (बस मजाक कर रहे हैं - धन्यवाद)
dcromley

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.