13

我正在开发一个使用画布自动裁剪图像,然后返回其数据 URL 的项目。它使用来自外部服务器的图像,该服务器具有适当的 CORS 标头,以允许图像在裁剪后转换为数据 URI,即使它们是跨域的。

该代码在除 IE 10 之外的所有浏览器中都能完美运行(并且没有安全错误!),其中在调用 canvas.toDataURL() 时会抛出“SCRIPT5022: SecurityError”。

这是 IE 中的错误还是我需要在代码中做不同的事情才能使其在 Idiot Exploder 中工作?谢谢。-斯科特

编辑 这是(大部分)我用来创建和绘制画布的代码;

var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = imageServerURL + '?id=' + imageIdToGet; // imageServerURL points to a different domain but the server has headers allowing requests from my domain
/*
    code here that defines the cropping area, in variables like ulX, lrY, etc.
*/
ctx.beginPath();
ctx.moveTo(ulX, ulY);
ctx.lineTo(urX, urY);
ctx.lineTo(lrX, lrY);
ctx.lineTo(llX, llY);
ctx.closePath();
ctx.clip();
ctx.drawImage(img, 0, 0);
var url = canvas.toDataURL(); // This succeeds in all other browsers but throws a SecurityError in IE
4

2 回答 2

20

不幸的是,即使正确设置了 CORS 标头,IE10 仍然是唯一不支持将 CORS 绘制到 Canvas 的图像的流行浏览器。但是即使没有在服务器端代理图像,也可以通过 XMLHttpRequest 解决此问题:

var xhr = new XMLHttpRequest();
xhr.onload = function () {
    var url = URL.createObjectURL(this.response);
    img.src = url;

    // here you can use img for drawing to canvas and handling

    // don't forget to free memory up when you're done (you can do this as soon as image is drawn to canvas)
    URL.revokeObjectURL(url);
};
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.send();
于 2013-11-01T20:03:52.773 回答
6

我不相信 IE10 对图像有 CORS 支持。 这篇 MDN 文章似乎支持了这一点。

正如文章所述:

尽管您可以在画布中使用未经 CORS 批准的图像,但这样做会污染画布。一旦画布被污染,您就不能再将数据拉出画布。例如,您不能再使用画布的 toBlob()、toDataURL() 或 getImageData() 方法;这样做会引发安全错误。

因此,在尝试执行此操作之前,您似乎必须从与托管相关代码的源/域相同的源/域中代理图像,至少对于 IE10 和 Opera 而言。

要处理不支持 CORS 图像的浏览器,您需要代理图像服务器端。您可以通过将图像的源发送到本地服务器上的已知端点,并将图像的源 URL 作为查询参数传递来轻松完成此操作。

例如:

var sourceImageUrl = "https://www.google.com/images/srpr/logo4w.png",  
    localProxyEndpoint = "/imageproxy",   
    image = new Image();   

image.src = localProxyEndpoint + "?source=" + encodeURIComponent(sourceImageUrl);

现在,在服务器端,您将处理这个 GET 请求,source从 URI 中提取参数值,从源中获取图像,并在响应中返回它。

于 2013-08-07T20:18:25.573 回答