Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported

1:背景

最近在做一个图片内容识别的项目,采用的是阿里巴巴的付费接口。大致流程为:

1:用户上传图片
2:将图片转为base64的格式发送给阿里的接口
3:阿里接口返回图片的内容信息

2:遇到的问题

这里边第二步转base64 ,我采用html5的canvas,将图片绘制到画布上,然后用canvas的 toDataURL 方法。
但是在图片转base64的过程中遇到了两个问题,

  • 1:图片无法绘制,转成的base64 用浏览器打开是空的透明画布,如图
 
image.png

代码片段如下:

  var canvas=document.getElementById("canvas"),//获取canvas
ctx = canvas.getContext("2d"), //对应的CanvasRenderingContext2D对象(画笔)
img = new Image(),//创建新的图片对象
base64 = '' ;//base64 img.src = 'http://www.xxxx.png';
ctx.drawImage(img,0,0);
base64 = canvas.toDataURL("image/png");

这个时候我想到问题应该是 图片还没加载完毕 就已经绘制了,既然是这样,那么修改为以下:

  var canvas=document.getElementById("canvas"),//获取canvas
ctx = canvas.getContext("2d"), //对应的CanvasRenderingContext2D对象(画笔)
img = new Image(),//创建新的图片对象
base64 = '' ;//base64
img.src = 'http://www.xxxx.png';
img.onload = function(){//图片加载完,再draw 和 toDataURL
ctx.drawImage(img,0,0);
base64 = canvas.toDataURL("image/png");
};

修改完毕我正要打算喝杯水庆祝一下,一刷新页面,一口老血喷了出来,chrome控制台又报错如下:

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
大概意思是canvas无法执行toDataURL方法:污染的画布无法输出,请原谅我的灵魂翻译。
经google 发现原来是受限于 CORS 策略,会存在跨域问题,虽然可以使用图像(比如append到页面上)但是绘制到画布上会污染画布,一旦一个画布被污染,就无法提取画布的数据,比如无法使用使用画布toBlob(),toDataURL(),或getImageData()方法;当使用这些方法的时候 会抛出一个安全错误
Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
具体详情附上一个链接非常详细如下:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image,非常值得一看,个人理解可能不到到位,还是建议读读这个链接。

解决方案:

图片设置 :crossOrigin属性
代码片段:img.setAttribute("crossOrigin",'Anonymous')

完整代码:

``
var canvas=document.getElementById("canvas"),//获取canvas
ctx = canvas.getContext("2d"), //对应的CanvasRenderingContext2D对象(画笔)
img = new Image(),//创建新的图片对象
base64 = '' ;//base64
img.src = 'http://www.xxxx.png';
img.setAttribute("crossOrigin",'Anonymous')
img.onload = function(){//图片加载完,再draw 和 toDataURL
ctx.drawImage(img,0,0);
base64 = canvas.toDataURL("image/png");
};

stackoverflow上解决方案:
地址:https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror

Tips:如果遇到其他canvas 关于SecurityError 的问题,也可以尝试一下这个解决方法。
另外经过多次搜索,总结了几个小窍门

1:使用google 。baidu搜索的都是转来转去的几篇文章,干扰太大。
2:首先搜索bug之家 :stackoverflow,总有解决你的bug的方案,链接:https://stackoverflow.com/
3:web文档之家:mozilla的web文档 ,非常权威,非常详尽。链接:https://developer.mozilla.org/en-US/

解决 canvas 下载含图片的画布时的报错的更多相关文章

  1. [解决] [centOS] g++ 带 -static 参数编译时,报错 /usr/bin/ld: cannot find -lm

    静态编译时缺少某个库 yum install glibc-static 从这里找到的 http://www.linuxquestions.org/questions/linux-software-2/ ...

  2. 【PostgreSQL】PostgreSQL添加新服务器连接时,报错“Server doesn't listen ”,已解决。

    PostgreSQL添加新的服务器连接时,报错:

  3. 安装vue-cli时-4058报错的解决方法

    一.报错信息 安装vue-cli时-4058报错 二.解决办法 1.安装淘宝镜像 npm --registry https://registry.npm.taobao.org info undersc ...

  4. 抓取https网页时,报错sun.security.validator.ValidatorException: PKIX path building failed 解决办法

    抓取https网页时,报错sun.security.validator.ValidatorException: PKIX path building failed 解决办法 原因是https证书问题, ...

  5. vs2010查看quartz.net 2.1.2的源码时其中一报错的解决方法

    问题: 使用vs2010查看quartz.net 2.1.2的源码时,报错: ..\Quartz.NET-2.1.2\server\Quartz.Server\Quartz.Server.2010.c ...

  6. 按照教程自动安装RFNoC时.在使用pip安装pybombs时出现报错,解决办法

    $ sudo apt-get install git $ sudo apt-get install python-setuptools python-dev python-pip build-esse ...

  7. Navicat 用ssh通道连接时总是报错 (报错信息:SSH:expected key exchange group packet form serve

    转:https://blog.csdn.net/qq_27463323/article/details/76830731 之前下了一个Navicat 11.0 版本 用ssh通道连接时总是报错 (报错 ...

  8. Python2.7在Windows下CMD编码为65001/utf-8时print报错[Errno 0]/[Errno 2]

    使用python2.7处理unicode的字符串,环境变量已设置PYTHONIOENCODING为utf-8,cmd编码为utf-8时print unicode字符串会报错[Errno 0]或[Err ...

  9. robotframework执行用例时,报错selenium.common.exceptions.WebDriverException: Message: unknown error: cannot get automation extension from unknown error: page could not be found: chrome-extension://aapnijgdinl

    在用robotframework编写移动端测试用例(用chrome浏览器模拟手机浏览器),执行用例时, 报错selenium.common.exceptions.WebDriverException: ...

随机推荐

  1. django之跨站请求伪造csrf

    目录 跨站请求伪造 csrf 钓鱼网站 模拟实现 针对form表单 ajax请求 csrf相关的两个装饰器 跨站请求伪造 csrf 钓鱼网站 就类似于你搭建了一个跟银行一模一样的web页面 , 用户在 ...

  2. Vi/Vim常用命令(附快捷切换方法)

    vi/vim有两种模式,正常(命令行)模式 和编辑模式,在命令行模式下,任何键盘输入都是命令,在编辑模式下,键盘输入的才是字符. 启动/关闭Vi/Vim 启动:vi 打开 Vi/Vim编辑器vi 文件 ...

  3. Cocos2d-x3.0网络通信学习(一)

    配置:win7+Cocos2d-x.3.0+VS2012 摘要:建立基本的http通信并得到返回信息. 一.添加项目与编译库 1.添加头文件 在需要用到Http网络相关类的文件中加入头文件 #incl ...

  4. 闲话复数(1) | 不现实的虚数 i 为什么虚?它长成什么样?

    原文 | https://mp.weixin.qq.com/s/y-Nb3S508UZuf_0GtRuNaQ 复数的英文是complex number,直译是复杂的数.最早接触复数大概是在高中时期,只 ...

  5. Objective-C中 #include 和 #import 的区别

    由于 Objective-C 兼容 C 语言,所以导入文件时, 可以使用 #include,也可以使用 #import (Objective-C 新增的) 如: #include <stdio. ...

  6. 编译出错:must be index or base register

    指令 mov ds:[dx],dx 原因:上述指令使用寄存器相对寻址方式,只能使用BX,BP,SI,DI 方括号里必须是变址(index,指SI, DI)或基址(base,指BX, BP)寄存器 正确 ...

  7. ETCD:HTTP JSON API通过gRPC网关

    原文地址:HTTP JSON API through the gRPC gateway etcd v3 使用 gRPC 作为消息协议.etcd项目包括一个基于gRPC的Go客户端和一个命令行工具,et ...

  8. ETCD:配置参数

    原文地址:Configuration flags etcd通过配置文件,多命令行参数和环境变量进行配置, 可重用的配置文件是YAML文件,其名称和值由一个或多个下面描述的命令行标志组成.为了使用此文件 ...

  9. RocketMQ 升级到主从切换(DLedger、多副本)实战

    目录 1.RocketMQ DLedger 多副本即主从切换核心配置参数详解 2.搭建主从同步环境 3.主从同步集群升级到DLedger 3.1 部署架构 3.2 升级步骤 3.3 验证消息发送与消息 ...

  10. 一起学SpringMVC之入门篇

    本文属于SpringMVC的入门篇,属于基础知识,仅供学习分享使用,如有不足之处,还请指正. 什么是SpringMVC ? SpringMVC是一个基于Spring的MVC框架,继承了Spring的优 ...