前端快照方案實踐

前言

首先聲明該文章是看了高質量前端快照方案:來自頁面的「自拍」@ 雲音樂前端技術團隊後實踐寫的筆記,爲了方便以後回顧,若是有小夥伴和我同樣遇到了相同的狀況也能夠有個參照。前端

實踐

高質量前端快照方案:來自頁面的「自拍」@ 雲音樂前端技術團隊原文章寫的很詳細,想要全面瞭解相關內容可查看原文,這裏爲只針對我我的的需求作一些合併圖片的分析。node

需求

根據用戶的二維碼和海報生成一張新的圖片分享出去。就涉及到將兩張圖片合成一張的需求。react

使用 canvas

第一想法就是使用 ctx.drawImage(),去繪製圖像,而後使用 ctx.toDataURL() 導出繪製圖像的地址。canvas

合併圖片的demo完整代碼api

// 核心代碼
let canvas = document.createElement('canvas')
let context = canvas.getContext('2d')
this.$refs.box1.onload = ()=>{
  // 畫布上第一次畫的內容,0,0表示座標
  context.drawImage(this.$refs.box1,0,0)
  // 畫布上第二次畫的內容,30,30表示座標,層級會比以前的高
  context.drawImage(this.$refs.box2,30,30)
  console.log('url',canvas.toDataURL());
}
複製代碼

瀏覽器安全限制

可能你使用了相同的 canvas api 去導出一個合併的圖片地址時發生如上報錯。緣由有兩點

  1. 你使用的圖片地址未設置容許跨域。在瀏覽器中輸入你的圖片地址查看,想我這張圖片存儲的服務器容許跨域訪問
  2. 瀏覽器中 img 元素是否設置了容許跨域,img 自己是沒有跨域問題的,可是使用 canvas api 如 toDataURL,toBlob,getImageData 因爲瀏覽器的限制會產生跨域問題。

解決跨域限制

根據產生跨域的緣由跨域

  1. 方式一就是將圖片存儲的服務設置 Access-Control-Allow-Origin*,若是使用外部的圖片地址,如微信的二維碼,可使用自家的服務作一層代理,拿node舉例設置以下
// 
const cors = require('@koa/cors')
app.use(
  cors()
)
複製代碼
  1. 寫一個接口,將圖片地址轉換成二進制的數據返回給客戶端,好處就是能夠解決多個不一樣域名下的圖片地址,而不須要將全部圖片都存儲在自家的服務器上。
// 服務端代碼
router.get('/image',async ctx=>{
  let url = await convertImage(ctx.query.url)
  ctx.set('Content-Type', 'image/png');
  ctx.set('Cache-Control', 'max-age=2592000');
  ctx.body = url
})
function convertImage(url) {
  return new Promise((resolve,reject)=>{
    request({
      url,
      encoding:'binary'
    },(error,response,body)=>{
      if (error) {
        console.log(error)
        reject(error)
    }
    // 返回二進制文件
    resolve( Buffer.from(body,'binary'))
    })
  })
}

// 客戶端代碼這裏因爲不是同源的,因此我把完整路徑都帶上了
<img src="http://localhost:9000/react/image?url=URL" alt="">
複製代碼

最後

只寫了本身使用合併圖片時解決的方案,更多詳細內容參考高質量前端快照方案:來自頁面的「自拍」@ 雲音樂前端技術團隊瀏覽器

相關文章
相關標籤/搜索