使用技术:
后端:node、egg、compressing
前端:原生js
实现流程:
后端:
- 1、获取object-name
let objectName = [ ‘original/97235090537395420T001R300x300M00000235pCx2tYjlq.jpg’, 'original/w320/h568/2923230346226924IMG_0030.mp4' ]; - 2、创建一个临时根目录
fs.mkdir('./a', (err) => {}); - 3、根据官方文档手动封装一个getStream,官方文档
async function getStream (objectName) { try { let result = await client.getStream(objectName); console.log(result); return result.stream; } catch (e) { console.log(e); } } - 4、因为打包必须要等.pipe()输出完,这里写了一个.pipe()监听方法
async writeStrem(path, result) { return new Promise(function (resolve, reject) { let writeStream = fs.createWriteStream(path); writeStream.on('close', function () { resolve(true) }) result.pipe(writeStream); }) } - 5、遍历object-name,流方式输出到根目录
for(let i = 0 , len = objectName.length ; i < len ; i++){ let result = await this.getStream(objectName[i]); // 截取original/后面的作为名字 let fileName = objectName[i].substring(objectName[i].lastIndexOf("/")+1); // 拿到的文件下载到临时文件里 result && (result.status !== false) && await this.writeStrem('./a/'+ fileName, result); } - 6、此时文件已经在a文件夹里面,进行压缩
await compressing.zip.compressDir('./a', './b.zip'); - 7、删除临时文件a fs.rmdir不能删除有文件的文件夹
let path = './a'; // 判断文件夹是否有文件 if( fs.existsSync(path) ) { // 定义名字数组 let files = []; // 文件名字添加到数组 files = fs.readdirSync(path); // 遍历文件名 files.forEach((file) => { let curPath = path + "/" + file; // 删除文件 fs.unlinkSync(curPath) }); fs.rmdirSync(path); } - 8、设置响应头文件,输出流文件
ctx.set("Content-Type", 'application/octet-stream'); let strem = fs.readFileSync('./b.zip'); ctx.body = strem;
前端:
- 1、 原生ajax请求
let xhr = new XMLHttpRequest(); xhr.open("post", `/downloadFile`, true); xhr.responseType = 'blob'; xhr.onload = function() { if (this.status == 200) { let blob = this.response; let url = window.URL.createObjectURL(blob); let link = document.createElement('a'); link.style.display = 'none'; link.href = url; link.setAttribute('download', 'b.zip'); document.body.appendChild(link); link.click() } } xhr.setRequestHeader('Content-Type', 'application/json'); // 传递数据 xhr.send();