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提供了跨域的設置。這樣就可以解決多次加載的問題。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章