दागी कैनवस का निर्यात नहीं किया जा सकता है


187

मैं अपने कैनवास को एक img में सहेजना चाहता हूं। मेरा यह कार्य है:

function save() {
    document.getElementById("canvasimg").style.border = "2px solid";
    var dataURL = canvas.toDataURL();
    document.getElementById("canvasimg").src = dataURL;
    document.getElementById("canvasimg").style.display = "inline";
}

यह मुझे त्रुटि देता है:

अनियोजित SecurityError: 'HTMLCanvasElement' पर 'toDataURL' को क्रियान्वित करने में विफल: दागी कैनवस को निर्यात नहीं किया जा सकता है।

मुझे क्या करना चाहिए?


किस ब्राउज़र में? stackoverflow.com/a/21362569/476716 का दावा है कि यह एक बग है।
ऑरेंजडॉग

1
क्रोम पर और फ़ायरफ़ॉक्स पर
user3465096

जवाबों:


180

सुरक्षा कारणों से, आपका स्थानीय ड्राइव "अन्य-डोमेन" घोषित किया गया है और कैनवास को दागदार करेगा।

(ऐसा इसलिए है क्योंकि आपकी सबसे संवेदनशील जानकारी आपके स्थानीय ड्राइव पर होने की संभावना है!)।

परीक्षण करते समय इन वर्कअराउंड की कोशिश करें:

  • अपने डेस्कटॉप पर सभी पेज संबंधी फाइलें (.html, .jpg, .js, .css, आदि) डालें (उप-फ़ोल्डरों में नहीं)।

  • अपनी छवियों को एक ऐसी साइट पर पोस्ट करें जो क्रॉस-डोमेन साझाकरण (जैसे ड्रॉपबॉक्स डॉट कॉम) का समर्थन करती है। सुनिश्चित करें कि आपने ड्रॉपबॉक्स के सार्वजनिक फ़ोल्डर में अपनी छवियां डाल दी हैं और छवि को डाउनलोड करते समय क्रॉस ओरिजिनल ध्वज भी सेट किया है (var img = Image); img.crossOrigin = "अनाम" ...)

  • अपने विकास कंप्यूटर पर एक वेबसर्वर स्थापित करें (IIS और PHP वेब सर्वर दोनों में मुफ्त संस्करण हैं जो स्थानीय कंप्यूटर पर अच्छी तरह से काम करते हैं)।


16
धन्यवाद, img.crossOrigin संपत्ति की स्थापना ने मेरी मदद की!
ज़ुमेक

5
@मार्क - मैंने फ़ाइल या किसी भी यूआरएल से लोड करने के बजाय लोकलस्टोरेज से इमेज डेटा लोड किया, फिर इसमें कुछ हेरफेर किया जैसे कि टेक्स्ट जोड़ना। फिर इसे toDataURL () का उपयोग करके स्थानीयस्टोरेज में वापस भेजने की कोशिश की। लेकिन यह दिखाता है कि "HTMLCanvasElement पर 'toDataURL को निष्पादित करने में विफल: दागी कैनवस को निर्यात नहीं किया जा सकता है"। इस मामले में मैं क्रॉस डोमेन समस्या प्राप्त करने के लिए किसी भी एक्सटर्नल फ़ाइल या यूआरएल का उपयोग नहीं कर रहा हूं। तो फिर इस त्रुटि में परिणाम क्यों है?
सजीथ

2
@ साइज - आप छवियों के लिए उपयोग किए गए पथ को सत्यापित करना चाह सकते हैं। मुझे भी यह समस्या थी, क्योंकि मैं अपने आईपी (127.0.xx /) के माध्यम से अपने स्थानीय वर्चुअल सर्वर पर सीधे परीक्षण कर रहा था, लेकिन कुछ छवियों को डोमेन (लोकलहोस्ट /) के माध्यम से जोड़ा गया था। एक बार जब मैंने लोकलहोस्ट का इस्तेमाल किया, तो इसने काम किया। तो सुनिश्चित करें कि आप कुछ इस तरह से चल रहे हैं।
विक्टर डी।

1
(1) इसे xampp वेबसर्वर से देखें, c के बजाय लोकलहोस्ट / फ़ाइल: / localdisk / फ़ाइल; तब क्रोम सुरक्षा त्रुटि के बारे में शिकायत नहीं करेगा। (2) या क्रोम शुरू करने पर इस झंडे का इस्तेमाल करें: - -लो-फाइल-एक्सेस-फ्रॉम-फाइल्स
mosh

1
बस एक और संभावित समस्या को जोड़ना: यदि आप एक कैनवस को निर्यात करने की कोशिश कर रहे हैं जिसमें एक विदेशीओबजेक्ट के साथ एक svg शामिल है, तो कुछ ब्राउज़र इसे दागी के रूप में चिह्नित करेंगे।
हेयरफॉटर

128

में img टैग सेट बेनामी को बेनामी।

<img crossorigin="anonymous"></img>

60
लेकिन html5 कैनवास के मामले में क्या करना है, एलिग तत्वों को नहीं
ग्राफिक्स

11
एक कैनवास तत्व के मामले में, समस्या का स्रोत हमेशा कुछ छवि (या छवियों) के साथ होता है जो आप उस पर ड्राइंग कर रहे हैं। तो आपको बस छवि को ट्रैक करने और उसके क्रॉसऑर्गिन विशेषता को निर्धारित करने की आवश्यकता है, इसे लोड करने से पहले।
फर्नांडो एचेवरिया

3
इससे मेरा दिन बच गया!
चांग

1
मदद करने के लिए खुश :)
अनीया मार्टिनेज

9
कार्यालय में इसका 12am im है और मुझे यह सरल उत्तर लगता है, यह शुद्ध खुशी है
धीरज

26

यदि कोई मेरे उत्तर पर विचार करता है, तो आप शायद इस अवस्था में हैं:

1. Openlayers (संस्करण> = 3) का उपयोग करके कैनवास में एक मानचित्र स्क्रीनशॉट प्राप्त करने की कोशिश कर रहा है
। 2. और निर्यात मानचित्र का उदाहरण देखा।
मानचित्र परत प्रदान करने के लिए ol.source.XYZ का उपयोग करना

बिंगो!

अपने भ्रम को हल करने के लिए ol.source.XYZ.crossOrigin = 'बेनामी' का उपयोग करना । या निम्नलिखित कोड की तरह:

     var baseLayer = new ol.layer.Tile({
         name: 'basic',
         source: new ol.source.XYZ({
             url: options.baseMap.basic,
             crossOrigin: "Anonymous"
         })
     });

1
बहुत खुबस। सभी स्रोतों के लिए उपयोगी है, जैसे टाइलइमेज और जैसे भी।
फिल

Fatastic! वास्तव में मैं अपने लिए क्या देख रहा था, एक OpenLayers डेमो Im कर के लिए आसान तय।
मार्क

मैं वेक्टर टाइल लेयर्स का उपयोग कर रहा हूं और इस प्रॉपर स्रोत को जोड़ने के बाद भी काम नहीं कर रहा हूं!
महदी n75

वास्तव में मुझे क्या चाहिए :)
रे

17

यदि आप ctx.drawImage()फ़ंक्शन का उपयोग कर रहे हैं , तो आप निम्न कार्य कर सकते हैं:

var img = loadImage('../yourimage.png', callback);

function loadImage(src, callback) {
    var img = new Image();

    img.onload = callback;
    img.setAttribute('crossorigin', 'anonymous'); // works for me

    img.src = src;

    return img;
}

और आपके कॉलबैक में अब आप उपयोग कर सकते हैं ctx.drawImage इसका उपयोग कर निर्यातtoDataURL


6
इसने मेरे लिए काम नहीं किया। अभी भी Tainted canvases may not be exported.त्रुटि संदेश मिल रहा है ।
सैम सेवरको

1
इससे मेरा काम बनता है। धन्यवाद। @SamSverko सुनिश्चित करें कि img.src से पहले विशेषता सेट करें।
ऐजोगा

14

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

<video id="video_source" crossorigin="anonymous">
    <source src="http://crossdomain.example.com/myfile.mp4">
</video>
  • पहुँच-नियंत्रण-अनुमति-मूल हेडर वीडियो स्रोत प्रतिक्रिया (crossdomain.example.com का उचित सेटअप) में सेट किया गया है
  • क्रॉसोरिगिन = "अनाम" होने के लिए वीडियो टैग सेट करें

5

ऐसा लगता है कि आप किसी ऐसे URL से छवि का उपयोग कर रहे हैं, जिसने Access-Control-allow-Origin-Header को सेट नहीं किया है और इसलिए यह समस्या है .. आप अपने सर्वर से उस छवि को प्राप्त कर सकते हैं और इसे अपने सर्वर से प्राप्त कर सकते हैं ताकि CORS मुद्दों से बच सकें।


क्या आप अपने उत्तर के बारे में अधिक सटीक हो सकते हैं, क्योंकि IM वास्तव में उस अवधारणा को नहीं जानता है। मैं अपने सर्वर से उस छवि को कैसे लाऊँ?
user3465096

आप उस छवि को कहां से ला रहे हैं, क्या यह आपके सर्वर या किसी अन्य से है?
प्रसन्न आरती

यह इस तरह से जाता है: loadImage ("example.jpg", 0, 0, 500, 300); मैं अपने कंप्यूटर में एक ही फोल्डर में रैंडम इमेज url या इमेज लगा सकता हूँ, फिर भी वही है
user3465096

हाँ, लेकिन मैंने अभी पेंट पर चित्र बनाया है और यह अभी भी वही है
user3465096

1
मैंने फ़ाइल के लिए Access-Control-Allow-Origin: * दिया, लेकिन फिर भी यह त्रुटि दिखा रहा है
हरिकृष्णन

4

मैंने useCORS: trueविकल्प का उपयोग करके समस्या का समाधान किया

 html2canvas(document.getElementsByClassName("droppable-area")[0], { useCORS:true}).then(function (canvas){
        var imgBase64 = canvas.toDataURL();
        // console.log("imgBase64:", imgBase64);
        var imgURL = "data:image/" + imgBase64;
        var triggerDownload = $("<a>").attr("href", imgURL).attr("download", "layout_"+new Date().getTime()+".jpeg").appendTo("body");
        triggerDownload[0].click();
        triggerDownload.remove();
    });

3

एमडीएन से [कॉर्स सक्षम छवि] [1] देखें। मूल रूप से आपके पास उचित पहुंच-नियंत्रण-अनुमति-मूल हेडर के साथ छवियों की मेजबानी करने वाला सर्वर होना चाहिए।

<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>

आप उन छवियों को DOM स्टोरेज में सहेजने में सक्षम होंगे जैसे कि उन्हें आपके डोमेन से सेवा दी गई थी अन्यथा आप सुरक्षा समस्या में चलेंगे।

var img = new Image,
    canvas = document.createElement("canvas"),
    ctx = canvas.getContext("2d"),
    src = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"; // insert image url here

img.crossOrigin = "Anonymous";

img.onload = function() {
    canvas.width = img.width;
    canvas.height = img.height;
    ctx.drawImage( img, 0, 0 );
    localStorage.setItem( "savedImageData", canvas.toDataURL("image/png") );
}
img.src = src;
// make sure the load event fires for cached images too
if ( img.complete || img.complete === undefined ) {
    img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
    img.src = src;
}


हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन उत्तर के आवश्यक भागों को शामिल करना और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक-केवल उत्तर अमान्य हो सकते हैं यदि लिंक किए गए पृष्ठ बदल जाते हैं। - समीक्षा से
गौतम शिव

सूचना के लिए धन्यवाद। मैं सिर्फ
एमडीएन

1

बस @ markE के उत्तर पर एक निर्माण के रूप में - यदि आप एक स्थानीय सर्वर बनाना चाहते हैं। आपके पास स्थानीय सर्वर पर यह त्रुटि नहीं होगी।

यदि आपके कंप्यूटर पर PHP स्थापित है:

  1. अपना टर्मिनल / सेमी खोलें
  2. उस फ़ोल्डर में नेविगेट करें जहां आपकी वेबसाइट की फाइलें हैं
  3. इस फ़ोल्डर में रहते हुए, कमांड चलाएं this php -S localhost:3000राजधानी को नोटिस करें, S ’
  4. अपना ब्राउज़र खोलें और URL बार में लोकलहोस्ट पर जाएँ: 3000 । आपकी वेबसाइट वहां चलनी चाहिए।

या

यदि आपके पास अपने कंप्यूटर पर Node.js स्थापित है:

  1. अपना टर्मिनल / सेमी खोलें
  2. उस फ़ोल्डर में नेविगेट करें जहां आपकी वेबसाइट की फाइलें हैं
  3. इस फ़ोल्डर में रहते हुए, कमांड चलाएँ npm init -y
  4. भागो npm install live-server -gया sudo npm install live-server -gएक मैक पर
  5. भागो live-serverऔर इसे स्वचालित रूप से आपकी वेबसाइट के साथ ब्राउज़र में एक नया टैब खोलना चाहिए।

ध्यान दें: अपने फ़ोल्डर की जड़ में एक index.html फ़ाइल रखना याद रखें, अन्यथा आपके पास कुछ समस्याएँ हो सकती हैं।


0

मैंने भी इस त्रुटि useCORS : true,को अपने कोड में जोड़कर हल किया -

html2canvas($("#chart-section")[0], {
        useCORS : true,
        allowTaint : true,
        scale : 0.98,
        dpi : 500,
        width: 1400, height: 900
    }).then();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.