javascript - Tilsmussede lerreter kan ikke eksporteres


Jeg vil lagre lerretet mitt til en img. Jeg har denne funksjonen:

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

Det gir meg en feil:

Ufanget SecurityError: Klarte ikke å utføre 'toDataURL' på 'HTMLCanvasElement': Tilsmussede lerreter kan ikke eksporteres.

Hva skal jeg gjøre?

Svar #1

Av sikkerhetsårsaker er din lokale stasjon erklært som «annet-domene» og vil forurense lerretet.

(Det er fordi din mest sensitive informasjon sannsynligvis er på din lokale disk!).

Mens du tester, prøv disse løsninger:

  • Legg alle side-relaterte filer (.html, .jpg, .js, .css, osv.) på skrivebordet ditt (ikke i undermapper).

  • Legg ut bildene dine på et nettsted som støtter deling på tvers av domener (som dropbox.com eller GitHub). Sørg for at du legger bildene dine i Dropbox sin offentlige mappe, og sett også på flagget for kryss-opprinnelse når du laster ned bildet (var img=new Image(); img.crossOrigin="anonymous" ...)

  • Installer en webserver på utviklingsdatamaskinen din (IIS og PHP-webservere har begge gratisutgaver som fungerer fint på en lokal datamaskin).

Svar #2

I img-taggen sett crossorigin til Anonymous.

<img crossorigin="anonymous" />

Svar #3

Hvis du bruker ctx.drawImage()-funksjonen, kan du gjøre følgende:

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

Og i tilbakeringingen din kan du nå bruke ctx.drawImage og eksportere det ved hjelp av toDataURL

Svar #4

Du kan være i denne tilstanden:

1. Prøver å få et kart-skjermbilde i canvas ved å bruke OpenLayers (versjon >= 3)
2. Og har sett eksemplet på å eksportere kart
3. Bruker ol.source.XYZ for å vise kartlag

Bingo!

Bruke ol.source.XYZ.crossOrigin='Anonymous' for å løse forvirringen din. Eller som følgende kode:

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

I OpenLayers6 er noe endret med ES6. Imidlertid er koden lik.

import { XYZ } from 'ol/source'
import { Tile as TileLayer } from 'ol/layer'
const baseLayer = new TileLayer({
    name : 'basic',
    source: new XYZ({
      url: 'example.tile.com/x/y/z', // your tile url
      crossOrigin: 'Anonymous',
      // remove this function config if the tile's src is nothing to decorate. It's usually to debug the src
      tileLoadFunction: function(tile, src) {
        tile.getImage().src = src
      }
    })
  })

Videre, ikke glem å sette access-control-allow-origin: * eller access-control-allow-origin: [dine godkjente opprinnelser] i responsheaderen hvis flisene blir forespurt på din egen server.

Slik:

Flere detaljer, og denne

Svar #5

I mitt tilfelle tegnet jeg på et canvas-element fra en video med noe som canvas.drawImage(video, 0, 0). For å håndtere feilen med forurenset canvas måtte jeg gjøre to ting:

<video id="video_source" crossorigin="anonymous">
    <source src="http://crossdomain.example.com/myfile.mp4">
</video>
  • Sørg for at Access-Control-Allow-Origin-headeren er satt i videokilderesponsen (riktig oppsett av crossdomain.example.com)
  • Sett videomerket til å ha crossorigin="anonymous"

Svar #6

Jeg løste problemet ved å bruke useCORS: true-alternativet

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

Svar #7

Ser ut som du bruker et bilde fra en URL som ikke har satt korrekt Access-Control-Allow-Origin-header, og derfor oppstår problemet. Du kan hente det bildet fra serveren din og få det fra serveren din for å unngå CORS-problemer.

Relaterte artikler