此文是半原创。

头像裁剪的主要实现是同事找来发我的,用着还不错。

记一下,可以用作以后研究。

此文主要记录一个要点:

当用户上传已上传头像,裁剪头像弹窗获取到图片,当调用canvas的toDataURL方法时可能会报:Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported这个错误。

百度上主要方法有2步:

一是给图片添加crossOrigin(具体添加在下方依赖js里有,此处只是简单说明)

 obj.image.crossOrigin = 'anonymous';

在HTML5中,一些 HTML 元素提供了对 CORS 的支持, 例如 <audio>、<img>、<link>、<script> 和 <video> 均有一个跨域属性 (crossOrigin property),它允许你配置元素获取数据的 CORS 请求。

二是给请求服务器配置相应的跨域(自行百度搜索吧,服务器我接触不到)

"Access-Control-Allow-Origin: *"

当然,这是网上最多的两种方式。如果还是不行(我的问题是即使经过了上面两个步骤,浏览器仍然提示跨域。),那就试试给请求图片加个时间戳吧。

obj.image.src = options.imgSrc + "?" + new Date().getTime()

我的难题到这一步已经解决了,至于为什么加时间戳可行,目前还不是很清楚。如果大佬愿意解此疑惑,欢迎评论。

。。。。。。。。。。。。。我又来了,自己照旧百度了一下这个问题。

发现有时候我们会在请求静态资源的时候添加时间戳,防止浏览器缓存。

于是我去掉时间戳,在谷歌浏览器控制台------network里面勾选disable cache 后,再次访问,成功获取图片。

也就是说浏览器先前已经缓存了我的图片地址,然而此时我又一次请求了它,并且请求的时候我设置了crossOrigin属性,可是缓存中的图片非CORS请求,所以浏览器直接就拒绝了请求

效果图:

<!DOCTYPE html>
<html lang="zh"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>头像裁剪</title><link rel="stylesheet" type="text/css" href="下面css" />
</head><body><div class="container"><div class="close" onclick="window.parent.topLayerService.hideTopLayer();">关闭</div><div class="box"><div class="imageBox" id="head_portrait"><div class="thumbBox"></div><div class="spinner" style="display: none">Loading...</div></div><div class="action"><div class="new-contentarea tc"><a href="javascript:void(0)" class="upload-img"><label for="upload-file">上传图像</label></a><input type="file" class="" name="upload-file" id="upload-file" /></div><input type="button" id="btnZoomIn" class="Btnsty_peyton" value="+" /><input type="button" id="btnZoomOut" class="Btnsty_peyton" value="-" /><input type="button" id="btnCrop" class="Btnsty_peyton" value="裁切" /></div></div><div class="cropped"><h2>效果预览</h2><div class="croppedImg"></div><div class="exhibition" id="exhibition"></div><input type="button" id="submit" class="Btnsty_peyton" value="确认修改" /></div></div><script type="text/javascript" src="../../../lib/jquery.js"></script><script type="text/javascript" src="下面js"></script><script type="text/javascript">$(window).ready(function () {var options ={thumbBox: '.thumbBox',spinner: '.spinner',imgSrc: ''}var cropper = $('.imageBox').cropbox(options);init();function init() {//初始获取用户头像图片,成功回调callback: function (data) {//渲染内容var nowdata = data[0];if (nowdata.head_portrait != undefined) {options.imgSrc = "XXXXXXXXXX.jpg";// 读取图片是否添加时间戳options.initFlag = true;cropper = $('.imageBox').cropbox(options);}}}// 切换图片$('#upload-file').on('change', function () {var reader = new FileReader();// file 将文件读取为 DataURLreader.readAsDataURL(this.files[0]);reader.onload = function (e) {options.imgSrc = e.target.result;// 读取图片是否添加时间戳options.initFlag = false;cropper = $('.imageBox').cropbox(options);}reader.onerror = function (e) {alert('图片上传失败,请检查。');}this.files = [];})// 裁切图片$('#btnCrop').on('click', function () {var img = cropper.getDataURL();$('.croppedImg').html('');$('.croppedImg').append('<div class="headerUP"><img src="' + img + '" align="absmiddle"></div><div class="headerSize">66px*66px</div>');// $('.cropped').append('<img src="' + img + '" align="absmiddle" style="width:128px;margin-top:4px;border-radius:128px;box-shadow:0px 0px 12px #7E7E7E;"><p>128px*128px</p>');// $('.cropped').append('<img src="' + img + '" align="absmiddle" style="width:180px;margin-top:4px;border-radius:180px;box-shadow:0px 0px 12px #7E7E7E;"><p>180px*180px</p>');})// 放大图片$('#btnZoomIn').on('click', function () {cropper.zoomIn();})// 缩小图片$('#btnZoomOut').on('click', function () {cropper.zoomOut();})// 提交$('#submit').on('click', function () {var files = new File([cropper.getBlob()], '.jpg', { type: 'image/jpg' });upload(files);});// 上传function upload(file) {var formData = new FormData();formData.append("file", file);formData.append("serviceToken", getCookie("serviceToken"));formData.append("time", getCookie("time"));formData.append("token", getCookie("serverToken"));formData.append("userid", getCookie("userid"));formData.append("serverToken", getCookie("serverToken"));$.ajax({url:"XXXXXXXXXXXXX",//上传服务type: "post",data: formData,async: false,cache: false,contentType: false,processData: false,success: function (data) {//发送获取用户信息成功后的回调callback: function (data1) {//渲染内容alert(data1 == "success" ? "更新头像成功" : "更新头像失败!"$("#exhibition").html("<img src='" + imageServerUrl + data.substr(12) + "'/>");}},error: function (XMLHttpRequest, textStatus, errorThrown) {console.info(XMLHttpRequest.status);console.info(XMLHttpRequest.readyState);console.info(textStatus);alert("文件上传失败!")},complete: function (XMLHttpRequest, textStatus) {this; // 调用本次AJAX请求时传递的options参数}});return false;}});</script>
</body></html>
/**   依赖js文件* Created by ezgoing on 14/9/2014.*/"use strict";
(function (factory) {if (typeof define === 'function' && define.amd) {define(['jquery'], factory);} else {factory(jQuery);}
}(function ($) {var cropbox = function (options, el) {var el = el || $(options.imageBox),obj ={state: {},ratio: 1,options: options,imageBox: el,thumbBox: el.find(options.thumbBox),spinner: el.find(options.spinner),image: new Image(),getDataURL: function () {var width = this.thumbBox.width(),height = this.thumbBox.height(),canvas = document.createElement("canvas"),dim = el.css('background-position').split(' '),size = el.css('background-size').split(' '),dx = parseInt(dim[0]) - el.width() / 2 + width / 2,dy = parseInt(dim[1]) - el.height() / 2 + height / 2,dw = parseInt(size[0]),dh = parseInt(size[1]),sh = parseInt(this.image.height),sw = parseInt(this.image.width);canvas.width = width;canvas.height = height;var context = canvas.getContext("2d");context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);//toDataURL将canvas对象转换为base64位编码 var imageData = canvas.toDataURL('image/png');return imageData;},//  将base64转成图片文件getBlob: function () {var imageData = this.getDataURL();var b64 = imageData.replace('data:image/png;base64,', '');var binary = atob(b64);var array = [];for (var i = 0; i < binary.length; i++) {array.push(binary.charCodeAt(i));}return new Blob([new Uint8Array(array)], { type: 'image/png' });},// 图片放大zoomIn: function () {this.ratio *= 1.1;setBackground();},//  图片缩小zoomOut: function () {this.ratio *= 0.9;setBackground();}},//  设置图片大小setBackground = function () {var w = parseInt(obj.image.width) * obj.ratio;var h = parseInt(obj.image.height) * obj.ratio;var pw = (el.width() - w) / 2;var ph = (el.height() - h) / 2;el.css({'background-image': 'url(' + obj.image.src + ')','background-size': w + 'px ' + h + 'px','background-position': pw + 'px ' + ph + 'px','background-repeat': 'no-repeat'});},imgMouseDown = function (e) {e.stopImmediatePropagation();obj.state.dragable = true;obj.state.mouseX = e.clientX;obj.state.mouseY = e.clientY;},imgMouseMove = function (e) {e.stopImmediatePropagation();if (obj.state.dragable) {var x = e.clientX - obj.state.mouseX;var y = e.clientY - obj.state.mouseY;var bg = el.css('background-position').split(' ');var bgX = x + parseInt(bg[0]);var bgY = y + parseInt(bg[1]);el.css('background-position', bgX + 'px ' + bgY + 'px');obj.state.mouseX = e.clientX;obj.state.mouseY = e.clientY;}},imgMouseUp = function (e) {e.stopImmediatePropagation();obj.state.dragable = false;},zoomImage = function (e) {e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio *= 1.1 : obj.ratio *= 0.9;setBackground();}obj.spinner.show();obj.image.onload = function () {obj.spinner.hide();setBackground();el.bind('mousedown', imgMouseDown);el.bind('mousemove', imgMouseMove);$(window).bind('mouseup', imgMouseUp);el.bind('mousewheel DOMMouseScroll', zoomImage);};obj.options.initFlag ? obj.image.src = options.imgSrc + "?" + new Date().getTime() : obj.image.src = options.imgSrc;obj.image.crossOrigin = 'anonymous';el.on('remove', function () { $(window).unbind('mouseup', imgMouseUp) });return obj;};jQuery.fn.cropbox = function (options) {return new cropbox(options, this);};
}));
/*
*   依赖css文件*/
.container {width: 660px;margin: 40px auto 0 auto;position: relative;color: #ffffff;font-size: 14px;box-shadow: -14px 0px 36px 7px rgba(108, 108, 108, 0.08);border-radius: 6px;overflow: hidden;
}
.close{width: 20px;height: 20px;background: url(../../../image/imageUp/guanbida1.png) no-repeat 0/100%;position: absolute;right: 8px;top: 8px;z-index: 3;font-size: 0;cursor: pointer;
}.container p {line-height: 12px;line-height: 0px;height: 0px;margin: 10px;color: #bbb;
}.action {width: 340px;height: 36px;position: absolute;bottom: 28px;left: 30px;
}.cropped {width: 270px;height: 502px;position: absolute;right: 0px;top: 0;box-shadow: 0px 0px 12px #ddd;text-align: center;background: #ffffff;
}
.cropped h2 {margin: 53px 0 34px;font-size: 16px;font-weight: 500;color: #333333;line-height: 16px;
}
.box {width: 390px;height: 502px;position: relative;overflow: hidden;background: rgba(0, 0, 0, 0.7);
}
.imageBox {width: 276px;height: 356px;margin: 44px auto 0;position: relative;/* overflow: hidden; */background-repeat: no-repeat;cursor: move;
}.imageBox .thumbBox {width: 200px;height: 200px;position: absolute;top: 50%;left: 50%;margin-top: -100px;margin-left: -100px;box-sizing: border-box;border: 1px solid rgb(102, 102, 102);
}.imageBox .spinner {text-align: center;line-height: 356px;background: rgba(255, 255, 255);position: absolute;top: 0;left: 0;bottom: 0;right: 0;color: #333333;
}.Btnsty_peyton {display: inline-block;*display: inline;*zoom: 1;vertical-align: top;width: 50px;height: 36px;padding: 0;margin-left: 4px;background: linear-gradient(0deg, #3377ff, #57a5ff);border-radius: 4px;outline: none;border: none;color: #ffffff;cursor: pointer;
}
#btnZoomIn {margin-left: 55px;background: url(../../../image/imageUp/zoomIn.png) no-repeat 0/100%;font-size: 0;
}
#btnZoomOut{background: url(../../../image/imageUp/zoomOut.png) no-repeat 0/100%;font-size: 0;
}
#btnCrop {width: 56px;
}
.croppedImg {height: 85px;text-align: center;
}
.headerUP {width: 66px;height: 66px;margin: 0 auto;border-radius: 100%;box-shadow: 0px 0px 12px #7e7e7e;overflow: hidden;
}
.headerUP img {width: 66px;height: 66px;
}
.exhibition {width: 246px;height: 180px;margin: 9px auto 67px;
}
.exhibition img{width: 246px;height: 180px;
}
.cropped .Btnsty_peyton {margin: 0 auto;width: 110px;height: 36px;
}/*选择文件上传*/
.new-contentarea {width: 110px;overflow: hidden;margin: 0 auto;position: relative;float: left;
}.new-contentarea label {width: 100%;height: 100%;display: block;
}.new-contentarea input[type="file"] {width: 110px;height: 36px;background: #333;margin: 0 auto;position: absolute;top: 0;left: 0;opacity: 0;filter: alpha(opacity=0);z-index: 2;
}a.upload-img {display: inline-block;*display: inline;*zoom: 1;width: 110px;height: 36px;line-height: 36px;background: linear-gradient(0deg, #3377ff, #57a5ff);border-radius: 4px;text-decoration: none;color: #ffffff;cursor: pointer;
}a.upload-img:hover {background-color: #ec7e70;
}.tc {text-align: center;
}

头像裁剪和Uncaught DOMException: Failed to execute ‘toDataURL‘ on ‘HTMLCanvasElement‘: Tainted canvases m相关推荐

  1. Uncaught DOMException: Failed to execute ‘toDataURL‘ on ‘HTMLCanvasElement‘: Tainted canvases may no

    未捕获的DomeException:未能在"HTMLCanvaElement"上执行"toDataURL":可能无法导出受污染的画布.出现这个bug的原因可能有 ...

  2. Uncaught SecurityError: Failed to execute ‘toDataURL‘ on ‘HTMLCanvasElement‘: Tainted canvases may

    一旦您将未经 CORS 批准从其他来源加载的任何数据绘制到画布中,画布就会被污染.受污染的画布不再被认为是安全的,任何从画布取回图像数据的尝试都将导致抛出异常. 在受污染的画布上调用以下任何一个都会导 ...

  3. Failed to execute ‘toDataURL‘ on ‘HTMLCanvasElement‘: Tainted canvases may not be exported.

    Intro 我在使用qrcode.react测试使用文本生成二维码的功能. 当执行以下API时,报错: let domTarget = event.target; let text = domTarg ...

  4. Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported [已解决]...

    原文链接: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported [已解 ...

  5. Fabric.js Failed to execute ‘toDataURL‘ on ‘HTMLCanvasElement‘: Tainted canvases may not be exported

    Fabric.js Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported ...

  6. html2canvas 报错:Failed to execute ‘toDataURL‘ on ‘HTMLCanvasElement : Tainted canvases may not be ...

    其实解决这个报错很简单,直接看下图: 把图中allowTaint改成false就好了哦!

  7. canvas生成图片toDataURL报错(Uncaught DOMException: Failed to execute ‘toDataURL‘ on ‘HTMLCanvasEl)

    现象:在使用canvas的toDataURL()方法时,控制台有时会报错:Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCa ...

  8. 视频截图Failed to execute ‘toDataURL‘ on ‘HTMLCanvasElement‘: Tainted canvas处理

    2021-10-14 背景 系统环境 报错原因 报错截图 处理过程 最终结果 背景 因为工作需要,所以研究了一下vue-video-player.使用起来很方便,但是也遇到一个不小的坑,搞的我欲仙欲死 ...

  9. @liveqing/liveplayer 视频截图Failed to execute ‘toDataURL‘ on ‘HTMLCanvasElement‘: Tainted canvas处理

    背景 因为工作需要,所以研究了一下LivePlayer H5直播|点播播放器.使用起来很方便,但是也遇到一个不小的坑,搞的我欲仙欲死. 系统环境 windows10.vue2.6.@liveqing/ ...

最新文章

  1. springboot集成neo4j
  2. 二叉树的深度优先和广度优先遍历
  3. linux 怎么重装libaprutil,Apache安装出错_cannot install `libaprutil-1.la' to a directory
  4. 35岁老程序员因身体原因没加班,老板:不想干就滚蛋
  5. java实现未读消息提醒_Android自定义View之未读消息提示
  6. webpack和react_使用React和Webpack进行简单的代码拆分
  7. OPPO沈义人官宣Reno首批配色:雾海绿、薄雾粉、极夜黑、星云紫
  8. Populating Additional data in Material master record
  9. Java IO编程全解(六)——4种I/O的对比与选型
  10. Quartus II13.0的破解过程
  11. Android 开源项目和文章集合(更新:2022.03.21)
  12. 基于微信小程序的物业维修报修系统设计与实现毕业设计毕设开题报告参考
  13. Kafka的监控以及运维与Kafka-eagle的安装
  14. 欧洲急了,正式发起 2nm 芯片总攻
  15. 深度 | 实景三维与CIM,谁才是时空数据第一底板 三维视频融合 三维投影融合 时空克隆 点卯-魔镜系列
  16. 计算机专业硕士论文能编吗,论文发表:计算机硕士论文编数据被发现怎么办?.docx...
  17. 树的先序/中序/后序遍历
  18. OSChina 周四乱弹 ——世界欠你一个奥斯卡
  19. 对Rapidly-exploring Random Trees(RRT)路径规划方法的理解
  20. ccache 3.1.9 发布,高速C/C++编译工具

热门文章

  1. 软件:快速共享win10文件夹
  2. 2012网易校园招聘杭州站笔试
  3. 震惊!!!某教育机构一男性教师讲课流程曝光!!!内容→面向对象(二)
  4. 计算机网络八股文(2022最新整理),太绝了
  5. Python简史:开发者的小副业如何成为全球最热编程语言?
  6. 唐筛的准确率这么低为什么还要做_唐氏筛查准确率这么低,为什么不能直接做羊水穿刺呢?...
  7. 给我未来的孩子--(转载)
  8. 八大人气运动 时尚MM必练
  9. 原子操作 临界区 关中断
  10. n 阶贝塞尔曲线计算公式——Ts实现