解决需要:当从其余编辑器粘贴过去内容且蕴含图片时,须要把图片传到本人的服务器。记录一下解决方案以及踩到的坑。

解析 html

从剪切板或者接口中拿到的 html 串,须要解析其中波及到的所有图片,此处咱们应用正则表达式。

let htmlContent = '拿到的html串'const { content, imgs } = this.getHtmlAndImgs(htmlContent)htmlContent = contentimgs.forEach(async item => {    const formData = await this.imgUrlToFomdata(item.url)    this.uploadToServer(formData, item.id)})
getHtmlAndImgs (htmlContent) {    const imgs = []    htmlContent = htmlContent.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => {        // match 匹配的整体值(该处是形似<img src="" />的内容)        // capture 正则匹配到的值(该处是形似 http://www.xxxxx.com 的图片链接地址)        // 排除属于本人的服务器地址        if (capture.includes('www.xxxxx.com')) {          return match        }        // this.count 初始值为0,imgs存储图片 id 和链接,不便通过操作dom来替换内容        const item = {          url: capture,          id: 'pasteImg' + (++this.count)        }        imgs.push(item)        // 将 html 中的图片地址替换,同时给每一张图片赋值 id        return match.replace(capture, '加载中的图片地址').replace(/<img/, `<img id="${item.id}"`)    });    return {        content: htmlContent,        imgs    }}

将图片地址转为 formdata 对象

这个中央有个须要留神的点是,fetch 会有同源跨域的问题,就算mode设置为no-cors也是有效的,如果申请的图片服务器做了限度,就须要去服务器设置nginx

不应用canvas转 base64 是因为无奈解决动图。
imgUrlToFomdata (url) {  return new Promise((resolve, reject) => {    fetch(url)      .then(respone => respone.blob())      .then(blob => {        const formData = new FormData();        const { type } = blob        const imgSuffix = type.substring(6)        // 不设置名字和后缀,接口会报错401,具体看后端接口代码        const fileName = `${new Date().getTime()}.${imgSuffix}`        const file = new File([blob], fileName, { type });        formData.append('file', file, fileName);        resolve(formData)      })      .catch(error => {        reject(error)      });  })}

将图片上传到服务器

将图片转换后的 formdata 二进制文件上传到服务器,并通过 id 从新设置图片地址为本人服务器的地址。

async uploadToServer (formData, id) {  const res = await this.$api.upload.blogImgUpload(formData);  const { code, data, message } = res.data;  if (code === 200) {    // 我的编辑器应用的是tinymce,获取编辑器内容的 dom 元素须要通过 activeEditor 获取    tinymce.activeEditor.getBody().querySelector(`#${id}`).src = data;  } else {    this.$message.error(message);  }}

至此,解决 html 并设置 img 的地址都处理完毕了。