最近項目中要實現(xiàn)圖片批量下載功能逸爵,最先用的cavas繪圖成base64批量下載圖片纽门,后來發(fā)現(xiàn)處理少量圖片可以用canvas繪圖没炒,下載圖片量太大會導(dǎo)致下載圖片緩慢更甚至性能不高的電腦會造成瀏覽器閃退浓领,所以這種方法行不通陶耍,代碼貼一下記錄一下:
方法一(不推薦):
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編碼數(shù)據(jù)
let a = document.createElement("a"); // 生成一個a元素
let event = new MouseEvent("click"); // 創(chuàng)建一個單擊事件
a.download = name || "photo"; // 設(shè)置圖片名稱
a.href = url; // 將生成的URL設(shè)置為a.href屬性
a.dispatchEvent(event); // 觸發(fā)a的單擊事件
a.remove() //移除a標(biāo)簽
};
image.src = imgsrc;
},
方法二:
后來嘗試使用xhr請求獲取blob數(shù)據(jù)奋蔚,多張圖片批量下載,一張圖片請求一次下載烈钞,后來發(fā)現(xiàn)原本要下載50張圖旺拉,下載后可能是25張产上?部分圖片貌似被瀏覽器吞了(也能是圖片命名相同導(dǎo)致瀏覽器認(rèn)為一樣的圖片沒必要重復(fù)下載棵磷,沒細(xì)查)....
方法三:
最后改變策略蛾狗,在方法二基礎(chǔ)上改造,第一步先使用xhr請求獲取blob數(shù)據(jù)仪媒,然后利用jsZip模塊把所有圖片文件都壓縮到一個文件中沉桌,壓縮后一次下載,發(fā)現(xiàn)下載的圖片是25個算吩,最后結(jié)合數(shù)組下綴改了不同文件名留凭,完美下載壓縮包,附代碼(前端框架使用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也有在線預(yù)覽壓縮文件功能蔼夜,具體見傳送門:http://www.reibang.com/p/e95718103e0a