Le tele contaminate non possono essere esportate


187

Voglio salvare la mia tela su un img. Ho questa funzione:

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

Mi dà errore:

Uncaught SecurityError: Impossibile eseguire "toDataURL" su "HTMLCanvasElement": non è possibile esportare i canvas contaminati.

Cosa dovrei fare?


In quale browser? stackoverflow.com/a/21362569/476716 afferma che si tratta di un bug.
OrangeDog,

1
su Chrome e su Firefox
user3465096

Risposte:


180

Per motivi di sicurezza, l'unità locale viene dichiarata "altro dominio" e contaminerà l'area di disegno.

(Questo perché le tue informazioni più sensibili sono probabilmente sul tuo disco locale!).

Durante il test prova queste soluzioni alternative:

  • Inserisci tutti i file relativi alla pagina (.html, .jpg, .js, .css, ecc.) Sul desktop (non in sottocartelle).

  • Pubblica le tue immagini su un sito che supporta la condivisione tra domini (come dropbox.com). Assicurati di mettere le tue immagini nella cartella pubblica di Dropbox e di impostare anche il flag di origine incrociata durante il download dell'immagine (var img = new Image (); img.crossOrigin = "anonymous" ...)

  • Installa un server web sul tuo computer di sviluppo (entrambi i server Web IIS e PHP hanno edizioni gratuite che funzionano bene su un computer locale).


16
Grazie, l'impostazione della proprietà img.crossOrigin mi ha aiutato!
zumek,

5
@markE - Ho caricato i dati delle immagini da localStorage invece di caricarli da un file o da qualsiasi URL, quindi ho fatto qualche manipolazione su di esso come l'aggiunta di un testo. Quindi ho provato a riportarlo in localStorage usando toDataURL (). Ma mostra "Impossibile eseguire 'toDataURL' su 'HTMLCanvasElement': le tele contaminate non possono essere esportate". In questo caso non sto usando alcun file exteranl o url per ottenere un problema tra domini. Allora perché sta causando questo errore?
Sajith,

2
@Saijth: potresti voler verificare il percorso utilizzato per le immagini. Ho avuto questo problema anche perché stavo testando l'accesso diretto al mio server virtuale locale attraverso il suo IP (127.0.xx /) ma alcune delle immagini erano collegate attraverso il dominio (localhost /). Una volta ho usato localhost invece ha funzionato. Quindi assicurati di non imbatterti in qualcosa del genere.
Victor D.

1
(1) Visualizzalo dal server Web xampp, localhost / file anziché da c: / localdisk / file; quindi Chrome non si lamenterà dell'errore di sicurezza. (2) Oppure usa questo flag quando avvii Chrome: --allow-file-access-from-files
mosh

1
Basta aggiungere un altro possibile problema: se stai cercando di esportare un canvas che contiene uno svg con un oggetto ForeignObject, alcuni browser lo contrassegneranno come contaminato.
HairyFotr

128

Nel tag img impostare crossorigin su Anonimo.

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

61
Ma cosa fare nel caso della tela html5, non degli elementi img
graphics123

11
Nel caso di un elemento canvas, l'origine del problema è sempre con qualche immagine (o immagini) su cui stai disegnando. Quindi devi solo rintracciare l'immagine e impostare l'attributo crossOrigin come indicato, prima di caricarlo.
Fernando Echeverria,

3
Questo mi ha salvato la giornata!
Chang

1
Felice di aiutarti :)
Annia Martinez,

9
sono le 12 del mattino, sono in carica e trovo questa semplice risposta, questa è pura felicità
Dheeraj,

26

Se qualcuno visualizza la mia risposta, forse sei in questa condizione:

1. Cercare di ottenere uno screenshot della mappa nell'area di disegno usando openlayer (versione> = 3)
2. E visualizzato l'esempio dell'esportazione della mappa
3. Usare ol.source.XYZ per eseguire il rendering del livello della mappa

Bingo!

Usando ol.source.XYZ.crossOrigin = 'Anonimo' per risolvere il tuo confuso. O come il seguente codice:

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

1
fantastico. Utile per tutte le fonti, come TileImage e simili.
Phil

Fatastic! Esattamente quello che cercavo, una soluzione semplice per una demo di OpenLayers.
Marc,

Sto usando i layer delle tessere vettoriali e dopo aggiungo questa proprietà alla fonte ma non funziona troppo!
mahdi n75,

Esattamente quello di cui avevo bisogno :)
Ray il

17

Se si utilizza la ctx.drawImage()funzione, è possibile effettuare le seguenti operazioni:

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

E nel tuo callback ora puoi usarlo ctx.drawImageed esportarlo usandotoDataURL


6
Questo non ha funzionato per me. Viene ancora visualizzato il Tainted canvases may not be exported.messaggio di errore.
Sam Sverko,

1
per me funziona. Grazie. @SamSverko assicurati di impostare l'attributo prima di img.src.
aijogja,

14

Nel mio caso stavo disegnando su un tag di tela da un video. Per risolvere l'errore di tela contaminato ho dovuto fare due cose:

<video id="video_source" crossorigin="anonymous">
    <source src="http://crossdomain.example.com/myfile.mp4">
</video>
  • Assicurati che l'intestazione Access-Control-Allow-Origin sia impostata nella risposta della sorgente video (impostazione corretta di crossdomain.example.com)
  • Imposta il tag video per avere crossorigin = "anonimo"

5

Sembra che tu stia utilizzando un'immagine da un URL che non ha impostato l'intestazione Access-Control-Allow-Origin corretta e quindi il problema. Puoi recuperare quell'immagine dal tuo server e ottenerla dal tuo server per evitare problemi CORS.


Potresti essere più preciso sulla tua risposta, perché non conosco davvero tutto quel concetto. Come posso recuperare quell'immagine dal mio server?
user3465096

da dove stai recuperando quell'immagine, viene dal tuo server o da qualche altra?
Prasanna Aarthi,

Va così: loadImage ("esempio.jpg", 0, 0, 500, 300); Posso inserire l'URL o l'immagine casuale nella stessa cartella del mio computer, è sempre la stessa
user3465096

sì, ma ho appena creato l'immagine su Paint ed è sempre la stessa
user3465096

1
Ho dato Access-Control-Allow-Origin: * per il file, ma continua a mostrare l'errore
Harikrishnan,

5

Ho risolto il problema utilizzando l' useCORS: trueopzione

 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

Guarda [Immagine abilitata CORS] [1] da MDN. Fondamentalmente è necessario disporre di un server che ospita immagini con l'intestazione Access-Control-Allow-Origin appropriata.

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

Sarai in grado di salvare quelle immagini su DOM Storage come se fossero state pubblicate dal tuo dominio, altrimenti potresti riscontrare problemi di sicurezza.

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


Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il collegamento come riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. - Dalla recensione
Gowtham Shiva,

Grazie per l'avviso. Ho appena aggiunto il contenuto dal link MDN :)
BerlinaLi

1

Proprio come una risposta alla risposta di @ markE, se si desidera creare un server locale. Non avrai questo errore su un server locale.

Se hai PHP installato sul tuo computer:

  1. Apri il tuo terminale / cmd
  2. Passare alla cartella in cui si trovano i file del sito Web
  3. Mentre sei in questa cartella, esegui il comando php -S localhost:3000← Nota la "S" maiuscola
  4. Apri il browser e nella barra degli URL vai su localhost: 3000 . Il tuo sito web dovrebbe essere in esecuzione lì.

o

Se hai Node.js installato sul tuo computer:

  1. Apri il tuo terminale / cmd
  2. Passare alla cartella in cui si trovano i file del sito Web
  3. In questa cartella, esegui il comando npm init -y
  4. Esegui npm install live-server -go sudo npm install live-server -gsu un mac
  5. Esegui live-servere dovrebbe aprire automaticamente una nuova scheda nel browser con il tuo sito Web aperto.

Nota: ricorda di avere un file index.html nella cartella principale della cartella, altrimenti potresti avere dei problemi.


0

Ho anche risolto questo errore aggiungendo il useCORS : true,mio codice come -

html2canvas($("#chart-section")[0], {
        useCORS : true,
        allowTaint : true,
        scale : 0.98,
        dpi : 500,
        width: 1400, height: 900
    }).then();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.