Canvas是HTML5新增的一个绘图标签,可以通过JavaScript在其中绘制各种图形,并且还支持将绘制内容导出为图片。然而,在某些情况下,我们在Canvas中加载跨域的图片时,会造成toDataURL()方法报错,这是由于浏览器的安全策略所致。接下来,我将就此问题作出详细说明,并提供两条示例说明。
问题描述
在Canvas中通过toDataURL()方法将绘制内容导出为png或者jpeg图片,如果绘制内容中包含跨域的图片,通常会出现以下的错误提示:
Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement':
Tainted canvases may not be exported.
at HTMLCanvasElement.toDataURL (<anonymous>)
此时,该方法无法正常执行,因此无法将绘制内容导出为图片。
问题原因
当Canvas中绘制的内容中包含跨域的图片时,浏览器通常会视其为不安全的资源。为了遵守同源策略,浏览器会禁止将跨域图片导出为图片。这是浏览器的安全机制所导致的。
解决方案
要解决这个问题,我们可以通过以下几种方法:
1. 使用代理服务器
使用代理服务器的方法是将跨域的图片通过代理服务器转发到本地,然后再在Canvas中加载本地图片。这样就可以避免跨域问题。以下是一个使用代理服务器的示例代码:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.crossOrigin = "Anonymous";
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL("image/png");
console.log(dataURL);
};
img.src = "http://example.com/image.png";
// 使用代理服务器
var proxyUrl = "https://cors-anywhere.herokuapp.com/";
var imageUrl = "http://example.com/image.png";
var xhr = new XMLHttpRequest();
xhr.open("GET", proxyUrl + imageUrl, true);
xhr.responseType = "blob";
xhr.onload = function() {
if (this.status === 200) {
img.src = URL.createObjectURL(this.response);
}
};
xhr.send();
2. 给图片添加CORS头
在跨域的图片请求时,给图片添加CORS头信息,这样浏览器就不会将其视为不安全的资源。以下是一个给图片添加CORS头的示例代码:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL("image/png");
console.log(dataURL);
};
img.src = "http://example.com/image.png";
以上是两种解决Canvas引入跨域的图片导致toDataURL()报错的问题的方法,开发者可以根据自己的情况选择更适合自己的方法来解决问题。