cropperjs 2.0裁剪图片后转base64提示“Tainted canvases may not be exported”跨域问题的解决办法。
目录
为什么会有这边文章
辛酸历程,不看也罢
想解决问题,看这里就够了
问题已解决,后边还是废话
为什么会有这边文章
最近,做一个项目需要用在前端实现图片裁剪功能,毋庸置疑,cropperjs是不二选择。当在项目中安装了cropperjs的时候,发现已经是2.0版本了,于是去粗略的看了一眼官方的文档(文档地址),感觉只是用到基本的裁剪功能,应该不会有什么大的变动。。。
辛酸历程,不看也罢
就在一切看似风平浪静的时候,最后在将裁剪好的图片调用toDataURL()转成base64格式的时候,问题出现了,浏览器报错“Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.”得知是因为图片跨域问题造成的,顺手就把问题抛给AI,AI也很快给出了解决方案,接下来复制-粘贴-运行,还是报错,而后又百度搜索,也没有具体的案例。。。
无奈之下,就去啃文档上,但是始终没有发现关于跨域这部分的内容。。。瞬间整个人都不好了。。。
这里省去一万字废话。。。
期间,想过放弃使用2.0,改用1.0版本,但是想了想不能做个轻易放弃的人,还是决定用2.0版本。抱着最后的希望去看了2.0的源码,结合着文档,原来2.0使用了自定义元素,在运行的项目中审查元素,看到的也都是自定义的元素,而不再是div和span了。
<!--Cropper 的默认模板:-->
<cropper-canvas background>
<cropper-image></cropper-image>
<cropper-shade hidden></cropper-shade>
<cropper-handle action="select" plain></cropper-handle>
<cropper-selection initial-coverage="0.5" movable resizable>
<cropper-grid role="grid" bordered covered></cropper-grid>
<cropper-crosshair centered></cropper-crosshair>
<cropper-handle action="move" theme-color="rgba(255, 255, 255, 0.35)"></cropper-handle>
<cropper-handle action="n-resize"></cropper-handle>
<cropper-handle action="e-resize"></cropper-handle>
<cropper-handle action="s-resize"></cropper-handle>
<cropper-handle action="w-resize"></cropper-handle>
<cropper-handle action="ne-resize"></cropper-handle>
<cropper-handle action="nw-resize"></cropper-handle>
<cropper-handle action="se-resize"></cropper-handle>
<cropper-handle action="sw-resize"></cropper-handle>
</cropper-selection>
</cropper-canvas>
想解决问题,看这里就够了
总之,上边全是废话,看这里就可以解决这个问题,哈哈哈哈哈。。。
<!-- cropperImg.vue 省略了无关代码 -->
<template>
<!--...省略无关代码 -->
<img class="cropperImg" id="cropperImg" :src="state.imgUrl" />
<el-button @click="getBase64">转base64</el-button>
</template>
<script lang="ts" setup>
import {onMounted, reactive} from "vue"
//...省略无关代码
const state = reactive({
// cropper 实例
cropper: undefined as any
});
onMounted(() => {
initCropper();
});
// 初始化cropperjs实例
const initCropper = () => {
nextTick(() => {
state.cropper = new Cropper("#cropperImg");
// 获取到上边的 cropper-image 自定义的dom元素,并设置crossorigin=“anonymous”即可
// 没错!就这么简单,硬是搞了一天才解决
state.cropper.getCropperImage().crossorigin = "anonymous";
});
}
//获取截图并转换成base64
const getBase64 = async () => {
// 这里注意两点:
// 1、获取的是 selection(也就是裁剪框选中的部分)的canvas画布内容,而不是 这个画布(getCropperCanvas().$toCanvas());
// 2、2.0版本的cropperjs获取canvas内容改为了异步获取,所以这里需要用到 asnyc/await
let canvas = await state.cropper.getCropperSelection().$toCanvas();
// 然后就可以正常将选框的部分转换成base64字符串了
let base64 = canvas.toDataURL("image/jpeg");
//...
console.log("base64=", base64);
}
</script>
问题已解决,后边还是废话
上一篇博客还是2017年。。。已经过去了太长时间了,期间本人经历比较起伏,也比较曲折,不能多说了,说多了就显得矫情了,哈哈哈。。。
还是希望以后能简单纯粹一点,做个贪财好色的俗人。大龄码农,坚持把自己遇到的有价值的坑给大家分享一下,能坑一个是一个吧:)
唉唉唉,别着急撤!如果问题解决了,留个赞再走~