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.