Resolved! Uncaught (in promise) DOMException: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported

In my previous post, we created a Google Map Static API image using a Get URL. In one of my project, there was a requirement of HTML conversion into PDF document. So I wanted to add that Map Image into that PDF document. I used html2canvas and jsPDF libraries for that.

When I was trying to convert an HTML section with Google Static Map Image into the canvas, I faced a strange issue.

Uncaught (in promise) DOMException: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported.

After some research I got know that it was not a bug in any of the libraries I used, It was a limitation to prevent unauthorized use of external usage of images in canvas in HTML5. You can see Map Image URL in this post.

Solution

As a workaround

Step 1) Sent Google Map Static Image URL to my server.
Step 2) Copied that Map URL on my server drive using server-side PHP.
Step 3) Got server path of Image saved.
Step 4) Used same server Image in HTML to use in Canvas.

The error is resolved!

Sent Google Image URL

	var static_map_url = "https://maps.googleapis.com/maps/api/staticmap?zoom=10&size=640×400&maptype=roadmap&markers=size:tiny|color:red|30.7169883,76.8330253|30.7114557,76.8317369|30.7119279,76.8235093|30.712243,76.8220297|30.7150512,76.8079784|30.7213083,76.7907067|30.7264096,76.7828441|30.7213396,76.774751|30.7171749,76.7682014|30.7151268,76.7650023|30.7163263,76.759678|30.71427,76.7527271|30.715385,76.7467373|30.7170764,76.7443409|30.7131802,76.7451|30.7187821,76.7403061|30.7266779,76.7343813|30.7309712,76.7308235|30.7383655,76.7255853|30.7385615,76.7151868|30.7313655,76.7014216|30.7349253,76.6913214|30.7407748,76.6735898|30.7425823,76.6655533|30.7428764,76.6580402|30.7451003,76.6514753|30.7483464,76.6459199|30.7542727,76.636874|30.7567175,76.6349099|30.7621539,76.6308324|30.7926283,76.6067499|30.8303907,76.5802187|30.8339385,76.5791738|30.8381602,76.5751323|30.8425998,76.5678161|30.848149,76.5635087|30.8539883,76.5642188|30.9172623,76.5429607|30.9563641,76.5310456|30.9768876,76.5312937|30.9810667,76.5240747|30.9848781,76.5206062|30.991882,76.5136958|30.982659,76.4996056|31.0067163,76.4150224|31.0081054,76.4111056|31.0318369,76.3783619|31.0430961,76.3895398|31.0612394,76.3961878|31.0659584,76.4008676|31.0705539,76.4048457|31.070745,76.4045751|31.0780614,76.4081158|31.0780614,76.4081158&path=color:0x0000ff|weight:3|30.7169883,76.8330253|30.7114557,76.8317369|30.7119279,76.8235093|30.712243,76.8220297|30.7150512,76.8079784|30.7213083,76.7907067|30.7264096,76.7828441|30.7213396,76.774751|30.7171749,76.7682014|30.7151268,76.7650023|30.7163263,76.759678|30.71427,76.7527271|30.715385,76.7467373|30.7170764,76.7443409|30.7131802,76.7451|30.7187821,76.7403061|30.7266779,76.7343813|30.7309712,76.7308235|30.7383655,76.7255853|30.7385615,76.7151868|30.7313655,76.7014216|30.7349253,76.6913214|30.7407748,76.6735898|30.7425823,76.6655533|30.7428764,76.6580402|30.7451003,76.6514753|30.7483464,76.6459199|30.7542727,76.636874|30.7567175,76.6349099|30.7621539,76.6308324|30.7926283,76.6067499|30.8303907,76.5802187|30.8339385,76.5791738|30.8381602,76.5751323|30.8425998,76.5678161|30.848149,76.5635087|30.8539883,76.5642188|30.9172623,76.5429607|30.9563641,76.5310456|30.9768876,76.5312937|30.9810667,76.5240747|30.9848781,76.5206062|30.991882,76.5136958|30.982659,76.4996056|31.0067163,76.4150224|31.0081054,76.4111056|31.0318369,76.3783619|31.0430961,76.3895398|31.0612394,76.3961878|31.0659584,76.4008676|31.0705539,76.4048457|31.070745,76.4045751|31.0780614,76.4081158|31.0780614,76.4081158&key=YOUR_API_KEY";

	var frData = {};
        frData.googleimage = static_map_url;
        frData.imagename = 'googe_map.png';
	    $.ajax({
            type: "post",
            url: "server/saveGoogleImage.php",
            data: frData,
            dataType: 'json',
            success: function(data) {
				var _c = new Date().getTime();
				$("#image_static_map").find("img").attr("src",data.imagepath);
				setTimeout(function(){ 		
					getPDF();
				}, 0);
				
            },
            error: function(data) {
                console.log("error");
            }
        });

HTML section

<div id="image_static_map" ><img src="" /></div>

Server side PHP

	$googleimage = $_REQUEST['googleimage'];
	$imagename = $_REQUEST['imagename'];

	
	$return_set=array();
	$return_set["results"]=array();
	
	if(!@copy($googleimage,'./googleimage/'.$imagename))
	{
		$errors= error_get_last();
		echo "COPY ERROR: ".$errors['type'];
		echo "<br />\n".$errors['message'];
		
		$data_insert=array(
			"statusCode" => "0",
			"status" => "error",
			"message" => $errors['type']." ".$errors['message']
		);
		
		
	} else {
		$data_insert=array(
			"statusCode" => "1",
			"status" => "success",
			"message" => "map saved!",
			"imagepath" => "/myimages/$imagename"
		);
	}
	

	array_push($return_set["results"], $data_insert);
	
	echo json_encode($data_insert);

For details on getPDF() function see this post in detail on How to convert HTML to PDF document.

 

Leave a Comment

Your email address will not be published. Required fields are marked *