Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么canvas.toDataURL()会引发安全异常?_Javascript_Html_Canvas_Cross Domain - Fatal编程技术网

Javascript 为什么canvas.toDataURL()会引发安全异常?

Javascript 为什么canvas.toDataURL()会引发安全异常?,javascript,html,canvas,cross-domain,Javascript,Html,Canvas,Cross Domain,我没有得到足够的睡眠还是怎么了?这是下面的代码 var frame=document.getElementById("viewer"); frame.width=100; frame.height=100; var ctx=frame.getContext("2d"); var img=new Image(); img.src="http://www.ansearch.com/images/interface/item/small/image.png" img.onload=function

我没有得到足够的睡眠还是怎么了?这是下面的代码

var frame=document.getElementById("viewer");
frame.width=100;
frame.height=100;

var ctx=frame.getContext("2d");
var img=new Image();
img.src="http://www.ansearch.com/images/interface/item/small/image.png"

img.onload=function() {
    // draw image
    ctx.drawImage(img, 0, 0)

    // Here's where the error happens:
    window.open(frame.toDataURL("image/png"));
}
正在抛出此错误:

SECURITY_ERR: DOM Exception 18

这不可能不起作用!有人能解释一下吗?

您的ID中不能有空格

更新

我的猜测是,图像位于与执行脚本的服务器不同的服务器上。在我自己的页面上运行时,我能够复制您的错误,但在我使用托管在同一域上的图像时,它工作正常。因此,它与安全相关-将图像放在您的站点上。有人知道为什么会这样吗?

杂志上说:

每当 画布元素,其原点清除标志为 如果设置为false,则调用该方法 必须引发安全错误异常


如果映像来自另一台服务器,我认为您不能使用toDataURL()

如果映像宿主能够为映像资源提供以下HTTP头并且浏览器支持CORS,那么似乎有一种方法可以防止这种情况发生:

access-control-allow-origin: * access-control-allow-credentials: true 访问控制允许来源:*
访问控制允许凭据:true
此处说明:

如果映像托管在设置访问控制允许源或访问控制允许凭据的主机上,则可以使用跨源资源共享(CORS)

您的另一个选择是让服务器有一个端点来获取和服务图像。(例如) 这种方法的缺点是延迟和理论上不必要的抓取


如果有更多的替代解决方案,我会有兴趣了解它们。

在图像对象上设置跨原点属性对我来说很有效(我使用的是fabricjs)

对于使用fabricjs的用户,以下是如何修补Image.fromUrl

// patch fabric for cross domain image jazz
fabric.Image.fromURL=function(d,f,e){
    var c=fabric.document.createElement("img");
    c.onload=function(){
        if(f){f(new fabric.Image(c,e))}
        c=c.onload=null
    };
    c.setAttribute('crossOrigin','anonymous');
    c.src=d;
};

我有同样的问题,所有的图像都在同一个域中托管。。。所以,如果有人有同样的问题,我是这样解决的:

我有两个按钮:一个用于生成画布,另一个用于从画布生成图像。它只对我有用,很抱歉我不知道为什么,当我在第一个按钮上写下所有代码时。所以当我点击它时,同时生成画布和图像


我总是有这个安全问题,当代码在不同的功能=/

如果您只是在画布上绘制一些图像,请确保您正在加载来自同一域的图像

www.example.com与example.com不同


因此,请确保您的图像和地址栏中的url是相同的,无论是否为www。

我可以使用以下方法使其正常工作:

在源服务器上的
.htaccess
的第一行写下此代码

Header add Access-Control-Allow-Origin "*"
然后在创建<代码>')[0] //还是纯粹的 var img=document.createElement('img'); img.src=http://your_server/img.png'; setAttribute('crossOrigin','anonymous');
我终于找到了解决方案。只需在
fromURL
func中添加
crossOrigin
作为第三个参数

// jQuery
var img = $('<img src="http://your_server/img.png" crossOrigin="anonymous">')[0]

// or pure
var img = document.createElement('img');
img.src='http://your_server/img.png';
img.setAttribute('crossOrigin','anonymous');

我使用的是fabric.js,可以通过使用toDatalessJSON而不是toDataURL来解决这个问题:

fabric.Image.fromURL(imageUrl, function (image) {
            //your logic
    }, { crossOrigin: "Anonymous" });

编辑:无需担心。这导致只将背景图像导出到JPG,而不在顶部绘制,因此它毕竟不是完全有用的。

如果攻击者能够猜出您在私人网站中的图片名称,则可以通过在画布上绘制并将新图像发送到其网站来获取该图片的副本。从我的观点来看,主要的限制是避免绘制另一个站点的内容,但是安全性太复杂了,因为攻击者可以在任何意外的站点中找到漏洞。请注意,子域也很重要。根据我的经验,至少在Chrome中,当进行一个被认为是跨子域的调用时,会引发一个SECURITY_ERR:DOM异常18:1。在中查找foo.example.com 2中的视频或图像。当转到与1中相同的页面时,请输入URL,然后尝试调用www.example中的视频或图像的toDataUrl()。com@AlfonsoML,也许我错了,但“如果攻击者能够猜出你在私人网站上的图片的名称”,他可能会用卷发器和浏览器抓取图像。我的观点:公共URL公共内容。@pop850即使在使用数据URL时,我也面临着这个问题。是否有一种方法可以解决数据URL的问题?@kilianc此限制旨在防止攻击者导致您的浏览器(带有身份验证cookie)获取图像并将其内容发送给攻击者;攻击者没有您的cookie,因此他无法使用curl获取您授权获取的相同资源。“公共URL,公共内容”是一种有缺陷的思维方式:我的Facebook页面有面向公众的组件,但有很多组件只有使用正确的身份验证令牌才能访问。您好,我就是这么做的,我有访问控制允许来源:*在图像上,我有crossorigin='anonymous',然后我在画布上绘制图像,然后我调用toDataUrl,仍然会得到安全性错误:DOM异常18访问控制允许凭据:true将不适用于访问控制允许源:*。当设置了前者时,后者应该有一个原点值,而不是通配符值(请参见此处了解解决方案):对于不使用AdobeAIR的人来说,该解决方案似乎没有用处。谢谢,它在Chrome中对我有用。我没有使用fabric.js,虽然我确实使用fabricjs,但无法解决它。您将如何使用此代码执行此操作?函数wtd_load_bg_image(img_url){if(img_url){var bg_img=new image();bg_img.onload=function(){canvasObj.setBackgroundImage(bg_img.src,canvasObj.renderal.bind(canvasObj),{originX:'left',originY:'top',left:0,top:0}};bg_img.src=img_url;}}也适用于Firefox。
fabric.Image.fromURL(imageUrl, function (image) {
            //your logic
    }, { crossOrigin: "Anonymous" });
canvas.toDatalessJSON({ format: 'jpeg' }).objects[0].src