当前位置: 首页 > news >正文

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年。。。已经过去了太长时间了,期间本人经历比较起伏,也比较曲折,不能多说了,说多了就显得矫情了,哈哈哈。。。

还是希望以后能简单纯粹一点,做个贪财好色的俗人。大龄码农,坚持把自己遇到的有价值的坑给大家分享一下,能坑一个是一个吧:)

唉唉唉,别着急撤!如果问题解决了,留个赞再走~

http://www.dtcms.com/a/130091.html

相关文章:

  • 0x03.Redis 通常应用于哪些场景?
  • 【从0到1搞懂大模型】transformer先导:seq2seq、注意力机制、残差网络等(6)
  • C++ 数据结构之图:从理论到实践
  • React(1)基础入门
  • 【模拟电路】PIN光电二极管和APD雪崩光电二极管
  • I/O进程5
  • fio的资料
  • 基于FPGA的一维时间序列idct变换verilog实现,包含testbench和matlab辅助验证程序
  • L1 第6次课 for循环
  • Python学生信息查询
  • Lesson 11 One good turn deserves another
  • AtCoder Beginner Contest 401 E题 题解
  • 文件包含靶场
  • sql 向Java的映射
  • docker compose搭建博客wordpress
  • 基于springboot的“流浪动物管理系统”的设计与实现(源码+数据库+文档+PPT)
  • Losson 4 NFS(network file system(网络文件系统))
  • 地毯填充luogu
  • 【CS*N是狗】亲测可用!!WIN11上禁用Chrome自动更新IDM插件
  • 使用PyTorch实现目标检测边界框转换与可视化
  • 深入探讨MySQL存储引擎:选择最适合你的数据库解决方案
  • 【微服务】SpringBoot 整合 Lock4j 分布式锁使用详解
  • 网络安全课程笔记整理
  • CTF--bp
  • Spring开发系列教程(15)——DAO
  • 力扣每日打卡 1922. 统计好数字的数目 (中等)
  • 时序约束高级进阶使用详解二:Set_Min_Delay
  • C++多线程编程时的伪共享问题及其定位和解决
  • LLMs之Agent之A2A:A2A的简介、安装和使用方法、案例应用之详细攻略
  • 制作一款打飞机游戏教程2:背景滚动