关于前端:解析html中的图片地址并传到自己服务器

10次阅读

共计 1738 个字符,预计需要花费 5 分钟才能阅读完成。

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

解析 html

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

let htmlContent = '拿到的 html 串'
const {content, imgs} = this.getHtmlAndImgs(htmlContent)
htmlContent = content
imgs.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 的地址都处理完毕了。

正文完
 0