在我们日常开发中,会遇到批量下载方面的问题;如上图所示,我们要批量下载图片,接下来我们就模拟实现这个功能,并将下载文件打包下载;
JSZip 是一个 javascript 库,用于创建、读取和编辑 .zip 文件,具有可爱而简单的 API。我们使用它来打包我们的下载文件;
下载完成以后,我们在dist里面可以找到相关js文件;
使用示例:
// 初始化一个zip打包对象 var zip = new JSZip(); // 创建一个被用来打包的名为Hello.txt的文件 zip.file("Hello.txt", "Hello World\n"); // 创建一个名为images的新的文件目录 var img = zip.folder("images"); // 这个images文件目录中创建一个base64数据为imgData的图像,图像名是smile.gif img.file("smile.gif", imgData, {base64: true}); // 把打包内容异步转成blob二进制格式 zip.generateAsync({type:"blob"}).then(function(content) { // content就是blob数据,这里以example.zip名称下载 // 使用了FileSaver.js saveAs(content, "example.zip"); }); /* 最终下载的zip文件包含内容如下: Hello.txt images/ smile.gif */
在上面的示例代码中,用到了FileSaver.js ,接下来我们介绍一下.
File Saver.js是在客户端保存文件的解决方案,对于在客户端生成文件的Web应用程序来说是完美的,但是如果该文件来自服务器,我们建议您首先尝试使用Content-Disposition附件响应头,因为它具有更多的跨浏览器兼容性。
使用示例:
var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"}); FileSaver.saveAs(blob, "hello world.txt");
更多用法,请阅读File Saver.js
请阅读XMLHttpRequest - Web API 接口参考 | MDN
请阅读FileReader - Web API 接口参考 | MDN
<script> //定义文件名称 var fileNames = ["小老头.jpg", "表情.png","pdf文件.pdf","excel文件.xlsx","故意错误文件.png"]; //文件下载路径 var urlsArr =["https://hx-pro.oss-cn-hangzhou.aliyuncs.com/68bb0ac4-af6e-41fa-9a91-462f128c82b5.jpg", "https://hx-pro.oss-cn-hangzhou.aliyuncs.com/48ccd15f-c12f-4346-b761-048b6f564fce.png", "https://hx-pro.oss-cn-hangzhou.aliyuncs.com/b1c6bf5e-b9e5-4381-bdb4-de440f674b12.pdf", "https://hx-pro.oss-cn-hangzhou.aliyuncs.com/1f60a6de-28d4-4e65-b213-c27a50dcd813.xlsx", "https://hx-pro.oss-cn-hangzhou.aliyuncs.com/404.png"] ;//大文件 //渲染好的base64数据 var base64Arr = new Array(urlsArr.length); //当前下载数量 var alreadyDrawingNum = 0; var zip = new JSZip(); //zip.file("readme.txt", "可在里面写相关信息"); //zip包里面的文件夹 var myFileZip = zip.folder("张三相关资料"); var saveFileName = "2019-12-30张三资料"; //开始渲染 getBase64ByAjax(urlsArr); //请求获取对应文件的base64码 function getBase64ByAjax(urlsArr) { for (let i = 0; i < urlsArr.length; i++) { let xhr = new XMLHttpRequest(); //初始化一个请求 xhr.open('get', urlsArr[i], true); xhr.diyData = { "thisIndex": i }; //一个用于定义响应类型的枚举值 xhr.responseType = 'blob'; //xhr.setRequestHeader("www11", "8899"); xhr.onload = function() { let thisFileindex = this.diyData.thisIndex; let thisFileStatus = this.status; console.log(this.diyData.thisIndex); if (thisFileStatus == 200) { var blob = this.response; var reader = new FileReader(); reader.readAsDataURL(blob); // 转换为base64,可以直接放入a标签href reader.onload = function(e) { //console.log(e.target.result); console.log(thisFileindex + "-200-" + thisFileStatus); base64Arr[thisFileindex] = ((e.target.result).split(',')[1]); //去头部 //通知渲染完成 alreadyDrawingNum = alreadyDrawingNum + 1; } } else { console.log(thisFileindex + "-504-" + thisFileStatus); fileNames[thisFileindex] = fileNames[thisFileindex] + "(!!此文件下载错误" + thisFileStatus + ").txt"; base64Arr[thisFileindex] = (""); //错误 //通知渲染完成 alreadyDrawingNum = alreadyDrawingNum + 1; } }; xhr.send(); } } //每个n时间看是否渲染完成,完成后保存 function isCompletedToBase64() { setTimeout(function() { console.log("****正在请求", alreadyDrawingNum); if (urlsArr.length == alreadyDrawingNum) { console.log("已完成渲染开始保存:", base64Arr); saveFile(); $("#xiazai").text("下载完成"); } else { $("#xiazai").append("."); console.log("下载了" + base64Arr.length); //可在html里面设置进度条 isCompletedToBase64(); } }, 100); } isCompletedToBase64(); $("#xiazai").text("正在下载"); function saveFile() { for (let i = 0; i < base64Arr.length; i++) { let fileName = fileNames[i]; //里面单独文件名 myFileZip.file(fileName, base64Arr[i], { base64: true }); } zip.generateAsync({ type: "blob" }).then(function(content) { // see FileSaver.js saveAs(content, "下载文件" + ".zip"); }); } </script>
效果图:
采用XMLHttpRequest ajax请求方式好处是:
1.能下载任意类型文件。
2.如果浏览器之前缓存过,可以从缓存里面直接加载图片。名字可以根据数组一一对应,网上方法一般不能对应名字。
3.自定义下载错误类型文本提示
源码下载:ajax请求方式打包下载所有类型文件源码
参考文章
1.JS实现zip打包文件并下载
2.浏览器中利用js打包下载所有类型文件