前端快照方案实践

前言

首先声明该文章是看了高质量前端快照方案:来自页面的「自拍」@ 云音乐前端技术团队后实践写的笔记,为了方便以后回顾,若是有小伙伴和我同样遇到了相同的状况也能够有个参照。前端

实践

高质量前端快照方案:来自页面的「自拍」@ 云音乐前端技术团队原文章写的很详细,想要全面了解相关内容可查看原文,这里为只针对我我的的需求作一些合并图片的分析。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="">
复制代码

最后

只写了本身使用合并图片时解决的方案,更多详细内容参考高质量前端快照方案:来自页面的「自拍」@ 云音乐前端技术团队浏览器

相关文章
相关标签/搜索