Bedorven doeken mogen niet worden geëxporteerd

Ik wil mijn canvas opslaan in een img. Ik heb deze functie:

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

Ik krijg een foutmelding:

Uncaught SecurityError: kan ‘toDataURL’ niet uitvoeren op ‘HTMLCanvasElement’: besmette canvassen kunnen niet worden geëxporteerd.

Wat moet ik doen?


Antwoord 1, autoriteit 100%

Om veiligheidsredenen wordt uw lokale schijf aangemerkt als ‘ander domein’ en zal het canvas aantasten.

(Dat komt omdat uw meest gevoelige informatie zich waarschijnlijk op uw lokale schijf bevindt!).

Probeer tijdens het testen deze tijdelijke oplossingen:

  • Zet alle paginagerelateerde bestanden (.html, .jpg, .js, .css, enz.) op uw bureaublad (niet in submappen).

  • Plaats je afbeeldingen op een site die delen tussen domeinen ondersteunt (zoals dropbox.com of GitHub). Zorg ervoor dat je je afbeeldingen in de openbare map van dropbox plaatst en ook de cross origin-vlag instelt wanneer je de afbeelding downloadt (var img=new Image(); img.crossOrigin="anonymous"…)

  • Installeer een webserver op uw ontwikkelcomputer (IIS- en PHP-webservers hebben beide gratis versies die goed werken op een lokale computer).


Antwoord 2, autoriteit 70%

Stel crossorigin in de img-tag in op Anoniem.

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

Antwoord 3, autoriteit 14%

Als iemand mijn antwoord bekijkt, bevindt u zich misschien in deze toestand:

1. Proberen een kaartschermafbeelding in canvas te krijgen met openlagen (versie >= 3)
2. En het voorbeeld bekeken van kaart exporteren
3. ol.source.XYZ gebruiken om kaartlaag te renderen

Bingo!

Gebruik ol.source.XYZ.crossOrigin = ‘Anoniem’om je verwarring op te lossen.
Of zoals de volgende code:

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

In OpenLayers6 is er iets veranderd met ES6. De code is echter vergelijkbaar.

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

Vergeet bovendien niet om access-control-allow-origin: *of access-control-allow-origin: [your whitelist origins] in de antwoordheader als de tegels op uw eigen server worden opgevraagd.
Zoals dit:

Meer detailsen deze


Antwoord 4, autoriteit 12%

Als u de functie ctx.drawImage()gebruikt, kunt u het volgende doen:

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

En in je callback kun je nu ctx.drawImagegebruiken en exporteren met toDataURL


Antwoord 5, autoriteit 8%

In mijn geval tekende ik op een canvastag uit een video. Om de bedorven canvasfout aan te pakken, moest ik twee dingen doen:

<video id="video_source" crossorigin="anonymous">
    <source src="https://crossdomain.example.com/myfile.mp4">
</video>
  • Zorg ervoor dat de header Access-Control-Allow-Origin is ingesteld in de reactie van de videobron (juiste configuratie van crossdomain.example.com)
  • Stel de videotag in op crossorigin=”anonymous”

Antwoord 6, autoriteit 4%

Ik heb het probleem opgelost met behulp van useCORS: trueoptie

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

Antwoord 7, autoriteit 3%

Het lijkt erop dat u een afbeelding gebruikt van een URL die niet de juiste Access-Control-Allow-Origin-header heeft ingesteld en vandaar het probleem. U kunt die afbeelding van uw server ophalen en van uw server halen om CORS-problemen te voorkomen ..


Antwoord 8

Bekijk CORS-compatibele afbeeldingvan MDN.
In principe moet u een server hebben die afbeeldingen host met de juiste Access-Control-Allow-Origin-header.

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

Antwoord 9

Als aanvulling op het antwoord van @markE: als u een lokale server wilt maken. U heeft deze fout niet op een lokale server.

Als je PHP op je computer hebt geïnstalleerd:

  1. Open je terminal/cmd
  2. Navigeer naar de map waar uw websitebestanden zich bevinden
  3. Voer in deze map het commando php -S localhost:3000uit ← Let op de hoofdletter ‘S’
  4. Open je browser en ga in de URL-balk naar localhost:3000. Je website zou daar moeten draaien.

of

Als je Node.js op je computer hebt geïnstalleerd:

  1. Open je terminal/cmd
  2. Navigeer naar de map waar uw websitebestanden zich bevinden
  3. Voer in deze map het commando npm init -y
  4. . uit

  5. Voer npm install live-server -gof sudo npm install live-server -guit op een mac
  6. Voer live-serveruit en het zou automatisch een nieuw tabblad in de browser moeten openen met uw website open.

Opmerking:vergeet niet om een index.html-bestand in de hoofdmap van uw map te hebben, anders kunt u problemen ondervinden.


Antwoord 10

Ik heb deze fout ook opgelost door useCORS : true,toe te voegen aan mijn code zoals –

html2canvas($("#chart-section")[0], {
        useCORS : true,
        allowTaint : true,
        scale : 0.98,
        dpi : 500,
        width: 1400, height: 900
    }).then();

Antwoord 11

In mijn geval was ik het vanaf mijn bureaublad aan het testen, met een CORS-fout, zelfs nadat ik de afbeelding lokaal in een submap had opgeslagen.

Oplossing:

In mijn geval de map verplaatst naar de lokale server WAMP. Werkte perfect vanaf de lokale server.

Opmerking:
Werkt alleen als je de afbeelding lokaal hebt opgeslagen.

Other episodes