最近碰到一个需求,已经获得一系列的
url
,想要去批量下载这一批文件,并且打包,生成一个zip压缩包。
单文件下载
使用axios或者原生的xhr都可以
downloadFile(url, fileName) { //跨域文件路径、下载到本地的文件名
var x = new XMLHttpRequest();
x.open("GET", url, true);
x.responseType = 'blob';
x.onload=function(e) {
var url = window.URL.createObjectURL(x.response)
var a = document.createElement('a');
a.href = url
a.download = fileName;
a.click()
}
x.send();
}
// 还可以用Promise来封装
getFile(url) {
return new Promise((resolve, reject) => {
axios({
method:'get',
url,
responseType: 'arraybuffer' // 这里可能为blob或者arrayBuffer
}).then(data => {
resolve(data.data)
}).catch(error => {
reject(error.toString())
})
})
}
将文本字符串转化成txt文件下载
downloadToTXT(txt, fileName) {
let blob = new Blob([txt]); // 首先要转化为blob对象
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = fileName + '.txt';
a.click();
},
文件批量打包
需要用到两个库,JsZip
和FileSaver
,可以cdn引入或者npm下载。
handleBatchDownload (urlList, zipName) {
const zip = new JSZip()
const cache = { } // 做缓存用
const promises = []
urlList.forEach(item => {
const promise = this.getFile(item).then(data => { // 下载文件, 并存成ArrayBuffer对象
const arr_name = item.split('/')
const file_name = arr_name[arr_name.length - 1] // 获取文件名
zip.file(file_name, data, { binary: true }) // 逐个添加文件
cache[file_name] = data
})
promises.push(promise)
});
Promise.all(promises).then(() => {
zip.generateAsync({ type: 'blob' }).then(content => { // 生成二进制流
FileSaver.saveAs(content, `${ zipName}.zip`) // 利用file-saver保存文件
})
});
}
- 在项目中,使用这个方法打包后,发现MP4和M4A格式的文件,打不开,可能是编码出现问题。现有解决方案可能有
webassembly + ffmpeg
,这个经过研究以后再补。
补充Base64下载
dataURLtoBlob(dataurl) {
// mime类型有时候通过base64字符串来获取,这里是直接写死了。
let mime = 'image/png',
bstr = window.atob(dataurl), n = bstr.length, u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
}
downloadFileByBase64(base64, name) {
let myBlob = dataURLtoBlob(base64)
let myUrl = URL.createObjectURL(myBlob)
this.downloadFile(myUrl, name)
}