canvas.toDataURL() 在 IE 11 中给出“安全错误”

Posted

技术标签:

【中文标题】canvas.toDataURL() 在 IE 11 中给出“安全错误”【英文标题】:canvas.toDataURL() gives "Security Error" in IE 11 【发布时间】:2015-07-18 00:43:57 【问题描述】:

我正在为需要对视频进行一些操作的媒体分销商开发基于浏览器的工具。

我有 html5 视频播放器,其中包含从另一个域(例如 http://video.com)加载的视频。域为视频返回以下标题(尝试使用带有 * 和特定域名的 ...-Origin):

Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: *

video 标签是这样的:

<video crossorigin="anonymous" src="http://video.com/video.mp4"></video>

我运行的JS如下:

        // meida is a reference to <video> tag
        var
            imgData,
            width = media.videoWidth,
            height = media.videoHeight,
            canvas = document.createElement("canvas"),
            context = canvas.getContext('2d');

        canvas.width = width;
        canvas.height = height;

        context.fillRect(0, 0, width, height);
        context.drawImage(media, 0, 0, width, height);

        imgData = canvas.toDataURL('image/png'); // line where IE throws DOMException named 'Security error'

该代码适用于除 IE 系列以外的所有浏览器。我已经在 IE 11 上试过了。

我知道在这种情况下画布会被污染,而它不应该被污染。

有没有人知道如何让它工作?我看到了一些图像的解决方法,但在我的情况下它不适用于 video

PS:我已经看到答案Canvas.toDataURL() working in all browsers except IE10,但它很老,并且与图像有关。我希望从那时起情况有所改变。

【问题讨论】:

按照此文档developer.mozilla.org/en-US/docs/Web/Security/…,我找到了一种解决方法。可以为应用程序设置tool.com 和为视频设置tool.com:8080 等域,然后 IE 假定视频来自与允许屏幕捕获的工具相同的位置。 @stephaska,如果它确实有效,您应该将其添加为答案并接受它 它实际上并没有解决问题。这是一个有很大限制的解决方法——两个主机都应该在同一个 IP 上。所以不幸的是,我不认为这是一个答案。 我们的客户坚持说我们支持 IE11 中的功能,所以我最终创建了后端流代理。 【参考方案1】:

我试图导出包含 highcharts 的页面的 pdf。 尝试在画布上加载 svg 数据时,我遇到了与 IE 相同的问题,同样的安全错误。

我使用 canvg.js 解决了这个问题

只包含canvg库文件,

在html页面上添加画布,

<canvas id="canvas"  ></canvas> 

使用下面的方法,

canvg(document.getElementById('canvas'), xml);

它适用于所有浏览器,包括 IE。

【讨论】:

这个问题很明显是关于视频的,你的解决方案肯定没有回答。 Ps:svg 在 IE 中污染画布是完全不同的问题,与 CORS 无关。【参考方案2】:

通过使用fabric js,IE 11中的“安全错误”将消失。

    var
        imgData,
        width = media.videoWidth,
        height = media.videoHeight,
        canvas = document.createElement("canvas"),
        fabCanvas  = new fabric.Canvas('c'),
        context = fabCanvas.getContext('2d');

    canvas.width = width;
    canvas.height = height;

    fabCanvas.fillRect(0, 0, width, height);
    fabCanvas.drawImage(media, 0, 0, width, height);

    imgData = fabCanvas.toDataURL(format: "png");

【讨论】:

context 没有使用,fillRect 和 drawImage 应该在上下文而不是画布上。但更重要的是:这不起作用......安全错误仍然发生

以上是关于canvas.toDataURL() 在 IE 11 中给出“安全错误”的主要内容,如果未能解决你的问题,请参考以下文章

在画布上调用 toDataUrl 时 IE 引发安全错误

canvas 2D API的1.2 toDataURL()方法

canvas.toDataURL() 导致安全错误

canvas.toDataURL() 用于大画布

canvas.toDataURL()报错

为啥 canvas.toDataURL() 会抛出安全异常?