• 解决 canvas 下载含图片的画布时的报错


    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/







  • 相关阅读:
    在Oracle中计算两个日期间隔的天数、月数和年数
    洛谷P1182 数列分段 Section II(二分+贪心)
    BZOJ1734 [Usaco2005 feb]Aggressive cows 愤怒的牛(二分答案+贪心)
    分治算法
    洛谷P1031 [NOIP2002]均分纸牌
    洛谷P1803 凌乱的yyy / 线段覆盖
    洛谷P1094 [NOIP2007]纪念品分组
    洛谷P1223 排队接水
    洛谷P1208 [USACO1.3]混合牛奶 Mixing Milk
    洛谷P1181 数列分段Section1
  • 原文地址:https://www.cnblogs.com/lguow/p/11978722.html
Copyright © 2020-2023  润新知