你不知道的图片批量下载

126 阅读1分钟

核心原理:利用a标签 download属性。但只限于同源URL,非同源的话会打开图片

在这里插入图片描述

so,首先,需要图片代理,以vue项目为例
//vue.config.js
module.exports = {
	...
	devServer: {
        proxy: {
            '/api/': {
                target: 'https://a.**.com.cn',
                ws: true,
                changeOrigin: true,
                pathRewrite: {
                    '^/api/': ''
                }
            },
            '/api1/': {
                target: 'https://img.**.com.cn',
                ws: true,
                changeOrigin: true,
                pathRewrite: {
                    '^/api1/': ''
                }
            },
            '/api2/': {
                target: 'https://pic1.**.com.cn',
                ws: true,
                changeOrigin: true,
                pathRewrite: {
                    '^/api2/': ''
                }
            }
        }
    }
}
其次,将图片转化为Blob,过程:img->base64->Blob
const translateImgToBase64 = (url) => {
  return new Promise((resolve) => {
    let canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    const img = new Image(); 
    img.onload = function () {
      canvas.width = img.width;
      canvas.height = img.height;
      context.drawImage(img, 0, 0); 
      const URLData = canvas.toDataURL('image/png');
      resolve(URLData);
      canvas = null;
    };
    img.onerror = function () {
      resolve();
    };
    img.src = url;
  });
}
const translateBase64ImgToBlob = (base64, contentType) => {
  const arr = base64.split(','); // 去掉base64格式图片的头部
  const bstr = atob(arr[1]); // atob()方法将数据解码
  let leng = bstr.length;
  const u8arr = new Uint8Array(leng);
  while (leng--) {
    u8arr[leng] = bstr.charCodeAt(leng); // 返回指定位置的字符的 Unicode 编码
  }
  const blob = new Blob([u8arr], { type: contentType });
  return URL.createObjectURL(blob); // 创建URL
}
当然,其中涉及到串联, data为数据源
let newList = []
let iToBPromise = Promise.resolve();
data.forEach((item, i) => {
  const tip = `转换进度:${(((i + 1) / data.length) * 100).toFixed(2)}%`;
  iToBPromise = iToBPromise.then(() => this.iToBEvent(item, tip));
});
iToBPromise = iToBPromise.then(() => {
    //此处进行图片下载操作,即下载newList中数据		
});
	
const iToBEvent = (item, tip) => {
  return new Promise((resolve) => {
    setTimeout(async () => {
      const res = await this.translateImgToBase64(item);
      if (res) {
        newList.push(               this.translateBase64ImgToBlob(res, 'image/jpeg'));
      } else {
        newList.push('');
      }
      console.log(tip);
      resolve();
    }, 200);
  });
}
最后,进行下载操作
<a :href="item" :download="index + 1" v-for="(item, index) in newList" :key="index">{{ item }}</a>
// script
const as = document.querySelectorAll('a');
let downImgPromise = Promise.resolve();
as.forEach((item) => {
  downImgPromise = downImgPromise.then(() => this.downImgEvent(item));
});
const downImgEvent = (item)=> {
  return new Promise((resolve) => {
    setTimeout(() => {
      item.click();
      resolve();
    }, 1000);
  });
}