最近项目中要实现图片批量下载功能,最先用的cavas绘图成base64批量下载图片,后来发现处理少量图片可以用canvas绘图,下载图片量太大会导致下载图片缓慢更甚至性能不高的电脑会造成浏览器闪退,所以这种方法行不通,代码贴一下记录一下:
方法一(不推荐):
downloadImage(imgsrc, name) {//下载图片地址和图片名
let image = new Image();
// 解决跨域 Canvas 污染问题
image.setAttribute("crossOrigin", "Anonymous");
image.onload = function() {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
let a = document.createElement("a"); // 生成一个a元素
let event = new MouseEvent("click"); // 创建一个单击事件
a.download = name || "photo"; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
a.remove() //移除a标签
};
image.src = imgsrc;
},
方法二:
后来尝试使用xhr请求获取blob数据,多张图片批量下载,一张图片请求一次下载,后来发现原本要下载50张图,下载后可能是25张?部分图片貌似被浏览器吞了(也能是图片命名相同导致浏览器认为一样的图片没必要重复下载,没细查)....
方法三:
最后改变策略,在方法二基础上改造,第一步先使用xhr请求获取blob数据,然后利用jsZip模块把所有图片文件都压缩到一个文件中,压缩后一次下载,发现下载的图片是25个,最后结合数组下缀改了不同文件名,完美下载压缩包,附代码(前端框架使用element ui):
安装模块:
npm install jszip
npm install file-saver --save
引入模块:
import JSZip from 'jszip'; //生成压缩文件模块
import FileSaver from "file-saver"; //保存文件模块
getBlob(url,cb) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function() {
if (xhr.status === 200) {
that.downCount++
cb(xhr.response);
}
};
xhr.send();
},
downFileSingle(){
let item = this.downlist[this.requestQueueIndex-1] //this.downlist下载文件列表
let arr = item.path.split('.')
let filename = '图片名称'+'.'+arr[arr.length-1]
this.downFile(item.path,filename)
},
downloadZip() {
let that = this
if(!this.downlist.length){
this.$message({
type:'warning',
message:'请选择要下载的图片'
})
return
}
var zip = new JSZip();
let appendFile = function(name, file) { //加入图片
zip.file(name, file);
}
let downloadZip = function() { //下载zip
return new Promise((resolve, reject) => {
zip.generateAsync({
type: "blob"
})
.then(function(content) {
// see FileSaver.js
FileSaver(content, `压缩文件_${that.downlist.length}.zip`)
that.downlist = []
resolve();
});
})
}
let getImageBlob = function(src) { //得到图片的blob
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open("get", src, true);
xhr.responseType = "blob";
xhr.onload = function() {
if(this.status == 200) {
var blob = this.response;
resolve(blob);
}
}
xhr.onerror = function() {
reject();
}
xhr.send();
});
}
this.loading = true;
let arr = [];
this.downlist.forEach((item, index) => {
console.log(item)
arr.push(getImageBlob( that.$fly.config.IMG_URL + item.path).then(blob => {
let arr = item.path.split('.')
let filename = '图片名称_' + index +'.'+arr[arr.length-1]
appendFile(filename, blob);
}).catch(err=>{
console.log(err)
})
);
});
Promise.all(arr).then(rs => {
downloadZip().then(rs => {
this.loading = false;
})
}).catch(ex => {
this.loading = false;
});
},
此方法也可类比打包下载其它文件,jsZIp也有在线预览压缩文件功能,具体见传送门:https://www.jianshu.com/p/e95718103e0a
网友评论