使用img.crossOrigin ="Anonymous"将图像绘制到画布不起作用

Joe*_*oey 16 javascript html5 canvas cors todataurl

在客户端独立的JS应用程序中,我正在努力实现它,所以我可以在画布上调用toDataURL(),在画布上我绘制了一些由URL指定的图像.即我可以在文本框中输入我要在画布上绘制的任何图像(托管在,例如,imgur)上的URL,单击"绘制"按钮,它将在画布上绘制.最终用户应该能够将他们的最终渲染保存为单个图像,因为我正在使用toDataURL().

无论如何,直到他们真正解决了令人讨厌的"操作不安全"错误(哎呀,你要告诉最终用户他们可以做什么,不能做他们自己的数据?)我按照一个解决方法说要添加图像到DOM并将其crossOrigin属性设置为"Anonmyous",然后将其绘制到画布上.

这是我的代码的完整工作简化版本(但实际上会有更多功能):

<!DOCTYPE html5>
<html>
<head>
<style>
#canvas {border:10px solid green;background-color:black;}
#imgbox {border:2px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width=336 height=336></canvas>
<br><br>
<input size=60 id="imgbox">
<input type="submit" value="Draw" onclick=draw()>
<script>
function draw() {
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    var img = new Image();
    img.src = document.getElementById("imgbox").value;
    img.crossOrigin = "Anonymous";
    context.drawImage(img, 40, 40);
}
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

如果没有该img.crossOrigin = "Anonymous";行,我可以输入http://i.imgur.com/c2wRzfD.jpg文本框并单击绘图,它会起作用.然而,只要我添加该行,整个事情就会破碎,甚至根本不会被绘制到画布上.

我需要更改什么来解决这个问题?我真的需要能够为最终用户实现保存最终图像的功能,并且编写html5规范的人故意介绍了这个bug,这非常令人讨厌.

小智 39

您必须在src 之前设置CORS请求- 只需将行交换为:

img.crossOrigin = "Anonymous";
img.src = document.getElementById("imgbox").value;
Run Code Online (Sandbox Code Playgroud)

您还需要为图像添加一个onload处理程序,因为加载是异步的:

img.onload = function() {
    context.drawImage(this, 40, 40);
    // call next step in your code here, f.ex: nextStep();
};
img.crossOrigin = "Anonymous";
img.src = document.getElementById("imgbox").value;
Run Code Online (Sandbox Code Playgroud)

  • @Joey你只能*请求*CORS使用,服务器可能会拒绝使图像加载失败的请求.您需要检查哪些服务器允许,哪些服务器不允许.对于那些不允许使用CORS的人,只需删除请求(crossOrigin行).对于无法使用CORS请求加载的图像,您需要将它们复制到您自己的服务器(与页面相同)或将它们移动到允许使用cors的另一台服务器.(希望有道理) (5认同)
  • 我不太明白 如果我以编程方式(使用javascript)生成了base64字符串,如果将其转换为png图像将只是随机像素,是否可以将其写入画布而不会出现cors错误? (2认同)
  • 我对这个 `img.crossOrigin = "Anonymous";` 感到困惑,当浏览器认为存在跨域的事情时,它似乎需要抛出安全错误。无论是否包含此行,Chrome 显示和链接到/从 `toDataURL("image/png");` 函数下载文件数据都没有问题,而 Safari 9.x 在所有情况下都无一例外地失败。而这一切都在同一个域中。 (2认同)