canvas.toDataURL() SecurityError

JavascriptCanvasCors

Javascript Problem Overview


So I'm using google maps and I get the picture so it looks like this

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

I need to save it. I have found this:

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,/, ""));

	};
}

But I get this problem:

> Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': tainted canvases may not be exported.

I searched for fixes. I found a sample here How to use CORS but still I can't tie these 2 pieces of code together to make it work. Maybe I'm doing it the wrong way and there is a simpler way to do it? I'm trying to save this pic so that I can transfer the data to my server. So maybe someone did something like this and knows how to make .toDataURL() work as I need it?

Javascript Solutions


Solution 1 - Javascript

Unless google serves this image with the correct Access-Control-Allow-Origin header, then you wont be able to use their image in canvas. This is due to not having CORS approval. You can read more about this here, but it essentially means:

> Although you can use images without CORS approval in your canvas, > doing so taints the canvas. Once a canvas has been tainted, you can no > longer pull data back out of the canvas. For example, you can no > longer use the canvas toBlob(), toDataURL(), or getImageData() > methods; doing so will throw a security error. > > This protects users from having private data exposed by using images > to pull information from remote web sites without permission.

I suggest just passing the URL to your server-side language and using curl to download the image. Be careful to sanitise this though!

EDIT:

As this answer is still the accepted answer, you should check out @shadyshrif's answer, which is to use:

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

This will only work if you have the correct permissions, but will at least allow you to do what you want.

Solution 2 - Javascript

Just use the crossOrigin attribute and pass 'anonymous' as the second parameter

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

Solution 3 - Javascript

This method will prevent you from getting an 'Access-Control-Allow-Origin' error from the server you are accessing to.

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

Solution 4 - Javascript

Try the code below ...

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

Solution 5 - Javascript

In my case I was using the WebBrowser control (forcing IE 11) and I could not get past the error. Switching to CefSharp which uses Chrome solved it for me.

Solution 6 - Javascript

I had the same error message. I had the file in a simple .html, when I passed the file to php in Apache it worked

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

Solution 7 - Javascript

if the picture from the third site didn't set the head of cors,you can never download the picture file through the chrome, even if you use the setAttribute('crossOrigin', 'anonymous'); Here are some suggestions

  1. hack the chrome
  2. write a program to download the picture and then use it with file

Solution 8 - Javascript

By using fabric js we can solve this security error issue in 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;
	}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3074343View Question on Stackoverflow
Solution 1 - JavascriptPrisonerView Answer on Stackoverflow
Solution 2 - JavascriptShady Mohamed SherifView Answer on Stackoverflow
Solution 3 - JavascriptCalvin FerrandoView Answer on Stackoverflow
Solution 4 - Javascriptct.tanView Answer on Stackoverflow
Solution 5 - JavascriptBrad MathewsView Answer on Stackoverflow
Solution 6 - JavascriptRodolfo Gutierrez NavaView Answer on Stackoverflow
Solution 7 - JavascriptJokerSoraView Answer on Stackoverflow
Solution 8 - JavascriptGanesan JsView Answer on Stackoverflow