我的编程空间,编程开发者的网络收藏夹
学习永远不晚

IE11下使用canvas.toDataURL报SecurityError错误怎么办

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

IE11下使用canvas.toDataURL报SecurityError错误怎么办

这篇文章主要介绍了IE11下使用canvas.toDataURL报SecurityError错误怎么办,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

发现问题

最近在项目中用到了 canvas 的 toDataURL 方法来获取图片的 base64 格式数据,用以上传到后台。由于之前也遇到过 canvas 被跨域图片污染不能获取数据的坑,因此这回一开始就机智的把 crossOrigin 属性值加上,代码大概如下:

const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
context.fillStyle = "black";
context.fillRect(0, 0, canvas.width, canvas.height);
const imageElement = document.createElement("img");
imageElement.crossOrigin = "Anonymous";
imageElement.onload = () => {
 context.drawImage(
 imageElement,
 params.left,
 params.top,
 canvas.width,
 canvas.height,
 0,
 0,
 canvas.width,
 canvas.height
 );

 const dataUrl = canvas.toDataURL("image/jpeg", 1);
}
imageElement.class="lazy" data-src = 'xxx';

本以为万无一失,而在 Chrome 浏览器上面也非常顺利;然而到了 IE11 上,却出现了一个莫名其妙的 SecurityError 错误:

IE11下使用canvas.toDataURL报SecurityError错误怎么办

没有具体的报错信息,只通过提示定位到了执行 toDataURL 这一行,实在让人疑惑。

尝试

第一时间 Google 了一下,发现很多人遇到这个问题,但是并没有看到什么有效的解决办法,有些人建议使用 Fabric.js,但是看了一下觉得太麻烦了点。而在 caniuse 上,也明确标注了该方法在 IE11 上有问题。

看起来应该是 IE 上的一个 bug,于是想到了一个曲线救国的办法:获取图片 base64 数据的办法又不是只有一个,既然 toDataURL 方法支持不好,那就用别的办法:

  • 先将 canvas 转成 blob

  • 再用 FileReader 以 dataUrl 的方式读取

代码大概如下:

const reader = new FileReader();
reader.readAsDataURL(canvas.msToBlob());
reader.onloadend = () => {
 const base64data = reader.result;
};

然而这并没有什么卵用....

这回轮到了 msToBlob 方法报了 SecurityError 错误。我:???

解决

看起来可能真的是安全原因,唯一的安全原因,只可能是跨域图片了。寻思着可能在 IE 上安全策略比较严格,即使设置了 crossOrigin = "Anonymous" 还是不让读数据,于是想到了另外一个思路,既然是因为跨域,那就把跨域因素去除:

  • 使用 ajax 请求拿到图片的二进制数据

  • 将二进制数据转为 base64 格式

  • 将得到的 base64 数据作为图片元素的 class="lazy" data-src 设置并画到画布上

  • 正常调用 toDataURL

代码大致如下:

// 之前的代码
// ...
// 最后一行 imageElement.class="lazy" data-src = 'xxx' 替换:
getDataUrlByclass="lazy" data-src('xxx').then(b64 => (imageElement.class="lazy" data-src = b64));

function getDataUrlByclass="lazy" data-src(class="lazy" data-src: string) {
 return new Promise<string>((resolve, reject) => {
 if (Cache.localGet("isIE")) {
  const xmlHTTP = new XMLHttpRequest();
  xmlHTTP.open("GET", class="lazy" data-src, true);

  // 以 ArrayBuffer 的形式返回数据
  xmlHTTP.responseType = "arraybuffer";

  xmlHTTP.onload = function(e) {
  
  // 1. 将返回的数据存储在一个 8 位无符号整数值的类型化数组里面
  const arr = new Uint8Array(xmlHTTP.response);
  
  // 2. 转为 charCode 字符串
  const raw = Array.prototype.map
   .call(arr, charCode => String.fromCharCode(charCode))
   .join("");
   
  // 3. 将二进制字符串转为 base64 编码的字符串
  const b64 = btoa(raw);
  
  const dataURL = "data:image/jpeg;base64," + b64;
  resolve(dataURL);
  };
  xmlHTTP.onerror = function(err) {
  reject(err);
  };
  xmlHTTP.send();
 } else {
  resolve(class="lazy" data-src);
 }
 });
}

尝试了一下,成功达到了目的。

后来查阅资料得知,如果 canvas 污染了,那无论是 toDataURL 还是 toBlob,都是无法执行成功的。

缺陷

虽然这个方法可以达到目的,但是却牺牲了性能。要先请求一次图片数据不说,数据编码的转换也是相当耗时的。小图还好,如果图片比较大,例如超过 3M ,那整个流程需要花费的时间可以达到一两分钟,这是不可接受的。

canvas的toDataUrl是否会压缩图像?

使用canvas的drawImage方法将image对象draw到canvas画布上时,图片大小会显著增加,并且只能保存为PNG格式。

将canvas用toDataUrl转化为base64,即使encoderOptions设置为1,图片也会有较大幅度的减小,但是比起最初的image还是要大。如果encoderOptions使用默认的0.92,最终的图片大小和初始的是相差不多的

感谢你能够认真阅读完这篇文章,希望小编分享的“IE11下使用canvas.toDataURL报SecurityError错误怎么办”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

IE11下使用canvas.toDataURL报SecurityError错误怎么办

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Linux下使用unzip命令报错怎么办

这篇文章将为大家详细讲解有关Linux下使用unzip命令报错怎么办,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。unzip命令是用于.zip格式文件的解压缩工具但是有时候在使用时遇到下面的错误。#xxx
2023-06-27

win10禁用windows错误报告怎么办

这篇文章给大家分享的是有关win10禁用windows错误报告怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、在任务栏的搜索框中输入“gpedit.msc”,然后回车确认打开 “本地组策略编辑器”。2、在
2023-06-28

vue中使用three.js报错怎么办

小编给大家分享一下vue中使用three.js报错怎么办,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言最近在学习three.js,同时也学习一下vue3,然后
2023-06-29

Jupyter Notebook内使用argparse报错怎么办

小编给大家分享一下Jupyter Notebook内使用argparse报错怎么办,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!Jupyter Notebook内使用argparse报错在github上下载了代码来学习时,
2023-06-15

django使用ajax post数据出现403错误怎么办

这篇文章将为大家详细讲解有关django使用ajax post数据出现403错误怎么办,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体内容请看下文。方法一:如果用jQuery来处理ajax的话,Djan
2023-06-08

使用OpenCV中的imread()内存报错怎么办

这篇文章给大家分享的是有关使用OpenCV中的imread()内存报错怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。错误截图如下:类似报错的原因1.imread()中的路径参数有误a.相对路径:此项目文件夹
2023-06-14

Linux系统使用cp命令报错cp:omitting directory怎么办

本篇内容介绍了“Linux系统使用cp命令报错cp:omitting directory怎么办”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
2023-06-13

使用zip出现No such file or directory报错怎么办

本文小编为大家详细介绍“使用zip出现No such file or directory报错怎么办”,内容详细,步骤清晰,细节处理妥当,希望这篇“使用zip出现No such file or directory报错怎么办”文章能帮助大家解决
2023-06-05

Win8系统应用商店下载程序出现错误代码0x80080206怎么办?

Win8系统应用商店下载程序出现错误代码0x80080206的解决方法:1、同时按住Win+R键调出运行对话框,然后在运行窗口中输入services.msc命令,打开服务功能面板;2、在Win8系统服务功能面板上,找到Windows Upd
2022-06-04

编程热搜

目录