canvas.toDataURL()SecurityError

时间:2013-12-06 12:45:51

标签: javascript canvas cors

所以我正在使用谷歌地图,我得到的图片看起来像这样

<img id="staticMap"
        src="http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap
&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318
&markers=color:red%7Ccolor:red%7Clabel:C%7C40.718217,-73.998284&sensor=false">

我需要保存它。我发现了这个:

function getBase64FromImageUrl(URL) {
    var img = new Image();
    img.src = URL;
    img.onload = function() {

        var canvas = document.createElement("canvas");
        canvas.width = this.width;
        canvas.height = this.height;

        var ctx = canvas.getContext("2d");
        ctx.drawImage(this, 0, 0);

        var dataURL = canvas.toDataURL("image/png");

        alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, ""));

    };
}

但是我遇到了这个问题:

  

Uncaught SecurityError:无法在'HTMLCanvasElement'上执行'toDataURL':可能无法导出受污染的画布。

我搜索了修复程序。我在这里找到了一个示例How to use CORS,但我仍然无法将这两段代码绑在一起以使其正常工作。也许我这样做的方式不对,有一种更简单的方法吗?我正在尝试保存此图片,以便我可以将数据传输到我的服务器。所以也许有人做了这样的事情并且知道如何让.toDataURL()在我需要的时候工作?

8 个答案:

答案 0 :(得分:90)

除非谷歌使用正确的Access-Control-Allow-Origin标题提供此图片,否则您将无法在画布中使用其图片。这是因为未获得CORS批准。您可以阅读有关此here的更多信息,但这实际上意味着:

  

虽然您可以在画布中使用未经CORS批准的图像,   这样做会玷污画布。一旦画布被污染,你就不能   更长的拉出数据从画布中退出。例如,你不能   更长时间使用canvas toBlob(),toDataURL()或getImageData()   方法;这样做会引发安全错误。

     

这可以防止用户使用图像暴露私有数据   未经许可从远程网站获取信息。

我建议只将URL传递给服务器端语言并使用curl下载图像。但要小心消毒!

修改

由于这个答案仍然是可以接受的答案,你应该查看@shadyshrif's answer,即使用:

var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;

如果您拥有正确的权限,会有效,但至少可以让您按照自己的意愿行事。

答案 1 :(得分:53)

只需使用crossOrigin attribute并传递'anonymous'作为第二个参数

var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;

答案 2 :(得分:4)

此方法将阻止您从正在访问的服务器收到“Access-Control-Allow-Origin”错误。

var img = new Image();
var timestamp = new Date().getTime();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url + '?' + timestamp;

答案 3 :(得分:3)

尝试以下代码......

<img crossOrigin="anonymous"
     id="imgpicture" 
     fall-back="images/penang realty,Apartment,house,condominium,terrace house,semi d,detached,
                bungalow,high end luxury properties,landed properties,gated guarded house.png" 
     ng-src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" 
     height="220"
     width="200"
     class="watermark">

答案 4 :(得分:0)

在我的情况下,我使用WebBrowser控件(强制IE 11),我无法通过错误。切换到使用Chrome的CefSharp解决了它。

答案 5 :(得分:0)

我有同样的错误信息。我将文件保存在一个简单的.html中,当我将该文件传递给Apache中的php时,它起作用了

html2canvas(document.querySelector('#toPrint')).then(canvas => {
            let pdf = new jsPDF('p', 'mm', 'a4');
            pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0, 211, 298);
            pdf.save(filename);
        });

答案 6 :(得分:-1)

如果第三站的图片没有设置cors头,永远无法通过chrome下载图片文件, 即使您使用 setAttribute('crossOrigin', 'anonymous'); 这里有一些建议

  1. 破解 chrome
  2. 编写一个程序来下载图片,然后将其与文件一起使用

答案 7 :(得分:-3)

通过使用fabric js,我们可以在IE中解决此安全错误问题。

    function getBase64FromImageUrl(URL) {
        var canvas  = new fabric.Canvas('c');
        var img = new Image();
        img.onload = function() {
            var canvas1 = document.createElement("canvas");
            canvas1.width = this.width;
            canvas1.height = this.height;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(this, 0, 0);
            var dataURL = canvas.toDataURL({format: "png"});
        };
        img.src = URL;
    }