fabric 使用网络URL导致toData导出出现跨域问题

问题描述

使用farbic.image生产图片的时候,需要将canvas导出成图片出现跨域问题
在这里插入图片描述

分析

这是由于canvas导出toDataURL不允许引用跨域的图片,所以出现报错。
通过阅读源码,发现其实fabric加载图片的时候是通过创建img标签来下载图片数据,所以只需要在img标签设置允许跨域即可解决这个问题。

img.crossOrigin = 'anonymous'

解决方案

第一种:把图片转为base64

案例:

let base64 = ''// 服务器传输base64代替url路径
let arr = base64.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8Arr=new Uint8Array(n)
while(n--){
	u8Arr[n] = bstr.charCodeAt(n)
}
// 变成二进制格式
let blod = new Blod([u8Arr],[type:mime])
let url = ''
 if (window.createObjectURL !== undefined) {
        // basic
   url = window.createObjectURL(blod)
} else if (window.URL !== undefined) {
        // mozilla(firefox)
   url = window.URL.createObjectURL(blod)
} else if (window.webkitURL !== undefined) {
        // webkit or chrome
   url = window.webkitURL.createObjectURL(blod)
}
// url保存的是本地临时路径,所以不会 出现跨域报错
// 由于不是加载的是本地文件,需要使用fabric提供的加载图片来加载,避免图片没有缓存时出现的不能正常刷新
  fabric.Image.fromURL(url, (img) => {
    let {width, height} = img
    let proportion = 1
    var oImg = img.set({ left: width / 2,
      top: height/ 2,
      originX: 'center',
      originY: 'center'
    }).scale(proportion)
    canvas.add(oImg)
    // 更新页面
    this.canvas.renderAll()
  })

第二种(推荐)使用fabric提供的参数允许跨域

	let url = 'http://'
   	let img = new Image()
    img.src = url
    img.crossOrigin = 'anonymous'// 跨域
    img.onload = () => {
       let { width, height } = img
    }
    var imgInstance = new fabric.Image(url, {
	    left: width/ 2,
	    top: height / 2,
	    originX: 'center',
	    originY: 'center',
	    crossOrigin: 'anonymous'// 跨域
	  }).scale(proportion)
	canvas.add(imgInstance)
	this.canvas.renderAll()

这里出现了2次设置跨域,并不多余。

  1. 第一次设置跨域时,为了当前的图片可以进行跨域加载
  2. 第二次设置跨域时,为了使得fabric中的toObjecttoJSON时能够保存到元素上的设置,这样使用loadCanvasFromObject的时候可以自动给图片设置跨域。

在我遇到问题的时候,发现国内只考虑到了一次加载的问题,就是设置加载图片的允许跨域。
但是由于我的数据是允许多次重复加载的,不可能每次使用时需要把图片单独抽取出来进行加载,所以通过查找文档和源码发现了,fabric提供了跨域的设置。这样就可以解决多次加载的问题。
fabric 使用网络URL导致toData导出出现跨域问题_第1张图片

你可能感兴趣的:(fabric,跨域)