Canvas
跨域如何解決?這裏記錄下使用 Canvas
繪圖過程當中所遇到的跨域問題和解決方案。web
先來看下實現方法。canvas
目標圖片通常是由 圖片 + 文本 構成。不管是千奇百怪的大小圖片,仍是變幻莫測的各式文本,都能用 canvas
api drawImage
和 fillText
方法來完成。api
基本流程以下:跨域
獲取 canvas
上下文 -- ctx
安全
const canvas = document.querySelector(selector) const ctx = canvas.getContext('2d')
繪圖網站
忽略圖片上的內容,直接用 drawImage
將其畫到 canvas
畫布上便可。this
const image = new Image() image.src = src image.onload = () => { ctx.save() // 這裏咱們採用如下參數調用 this.ctx.drawImage(image, dx, dy, dWidth, dHeight) this.ctx.restore() }
drawImage
有3種參數使用方式,具體用法能夠查看 MDN 文檔。rest
獲取圖像數據code
調用 HTMLCanvasElement
DOM 對象提供的 toBlob()
, toDataURL()
或 getImageData()
方法,便可。對象
canvas.toBlob(blob => { // 你要的 blob }, mimeType, encoderOptions)
這裏的 mimeType
默認值爲 image/png
。encoderOptions
指定了圖片質量,可用於壓縮,不過須要 mimeType
格式爲 image/jpeg
或者 image/webp
。
正常狀況下,若是須要將繪製好的圖像輸出,咱們能夠調用 canvas
的 toBlob()
, toDataURL()
或 getImageData()
方法來獲取到圖像數據。然而,遇到圖片跨域的狀況就有些尷尬了。可能回報以下錯誤:
Failed to execute 'toBlob' on 'HTMLCanvasElement': Tainted canvases may not be exported.
或者
Access to image at 'https://your.image.src' from origin 'https://your.website' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
先來看看第2種狀況。
Access-Control-Allow-Origin
若是你跨域使用某些圖片資源,而且該服務未正確響應 Access-Control-Allow-Origin
頭信息, 則會報出以下錯誤信息:
Access to image at 'https://your.image.src' from origin 'https://your.website' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
說明不容許跨域訪問,那麼你能夠試着讓後臺修改 Access-Control-Allow-Origin
的值爲 *
或 your.website
, 或者改用同域資源(考慮下?)。
接下來,咱們來解決第1種狀況。
img.crossOrigin = 'Anonymous'
爲避免未經許可拉取遠程網站信息而致使的用戶隱私泄露(如 GPS 等信息,具體可搜索 Exif),在調用 canvas
的 toBlob()
, toDataURL()
或 getImageData()
會拋出安全錯誤:
Failed to execute 'toBlob' on 'HTMLCanvasElement': Tainted canvases may not be exported.
若是你的圖片服務容許跨域使用(若是不容許,見上條),那麼你該考慮下給 img 元素加上 crossOrigin
屬性,即:
const image = new Image() image.crossOrigin = 'Anonymous' image.src = src
如此,你即可以拿到圖片數據了。若是沒招,換同域資源吧~