前端通过URL下载文件并转存到其他服务器(OSS)

近期遇到需求如下:

爬取到的html代码,需要将里面的所有图片资源,转存到oss,最后将新图片替换到HTML里

思路如下:

  1. 通过正则表达式提取所有图片
  2. 把图片资源下载并转存到oss
  3. 将转存后的图片资源替换到html代码里

提取所有图片,匹配所有<img>标签的图片与背景图片

/**
 * 1.提取所有图片(src="" && background-image)
 */
let imgArr = [];
let imgRegex = new RegExp('(?<=<img[^<]+\\ssrc=("|\'|")).*?(?=("|\'|").*?\/?>)|(?<=(background|border)(-image)?:\\s*url\\((\'|"|")).*?(?=(\'|"|")\\))', 'g');
imgArr = this.editor.document.body.innerHTML.match(imgRegex);
if (imgArr === null) {
  return;
}
// 去重
if (imgArr.length > 0) {
  imgArr = Array.from(new Set(imgArr.map(t => { return t; })));
}
console.log('提取所有图片,', imgArr);

图片转存OSS

/**
 * 2.图片转存OSS且将转存后的图片资源替换到html代码里
 */
for (let url of imgArr) {
  if (url === null) {
    continue;
  }
  let loadingInstance = Loading.service({text: '正在处理'});
  this.saveImg2Oss(url).then((res) => { // 图片转存oss
    console.log('图片转存oss成功,新地址--->>', res.new);
    res.old = res.old.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // 先转义
    let newBody = this.editor.document.body.innerHTML.toString();// 获取富文本
    var reg = new RegExp('(' + res.old + ')', 'g'); // 全部替换
    newBody = newBody.replace(reg, res.new); // 替换该图片
    that.editor.document.body.innerHTML = newBody; // 新的innerHTML
    loadingInstance.close();
  }).catch(error => {
    console.error('图片转存oss失败,' + error);
    loadingInstance.close();
  });
}

使用 XMLHttpRequest 对象获取图片url的Blob值

getImageBlob (url, cb) {
  let xhr = new XMLHttpRequest();
  xhr.open('get', url, true);
  xhr.responseType = 'blob';
  xhr.onload = function () {
    if (this.status === 200) {
      if (cb) {
        cb(this.response);
      }
    }
  };
  xhr.send();
},

转存图片至OSS

saveImg2Oss (url) {
  let that = this;
  return new Promise((resolve, reject) => {
    that.getImageBlob(url, function (blob) {
      const file = new window.File([blob], `abc.${blob.type.split('/')[1]}`, { type: blob.type });
      if (!that.ossUplpadInstance) {
        that.ossUplpadInstance = new OSSUpload();
      }
      // 替换成自己的上传OSS方法
      that.ossUplpadInstance.uploadFile({file: file}, (res) => {
        if (res.msg.length === 0) {
          let tempObj = {
            old: url,
            new: res.path
          };
          resolve(tempObj);
        } else {
          reject(res.msg);
        }
      }, (error) => {
          reject(error);
      }, (progress) => {});
    });
  });
}

最后实现效果:

原文链接:,转发请注明来源!

发表评论