Node.js服务将stream流转换为文件传给前端(导出文件给前端)

思路

1. 服务端生成文件,将文件在服务端的地址返回给前端供前端下载。

2. 服务端直接通过文件流传递给前端,前端直接将导出的接口地址使用window.open打开。(单纯的导出功能)

3. 服务端将文件流传给前端,前端将文件流转为blob对象并下载。

4. 服务端将文件流存在公共变量中,post请求上传文件后,再根据文件导出来进行请求。(只局限于每次上传并导入操作时,只有一个用户)

实战

写这篇帖子,主要是因为想做一个服务端接收前端待导入的excel,并判断excel中的错误数据,将错误数据收集后以excel的形式导出给前端。

在做这个内容的时候,由于知识面的狭窄走了很多弯路,特此写一篇博客来纪念一下。

服务端语言:node.js

前端框架:vue2

前端代码:前端方便比较简单,利用formData将文件信息上传给服务端,不细说了

服务端核心代码:

// service层

const upload = async ctx => {
    // 文件导出操作  
        //涉及模块:
        // 1. formidable 读取上传的文件信息
        // 2. fs 将文件暂存至本地
        // 3. xlsx 解析excel文件,转换为数组
        // 4. 导入数据并将错误数据收集
    

    //若存在错误数据
    if(wrongDataList){
        // 导出操作
        ctx.body = export(wrongDataList); 
    }
    else{
        ctx.body = "导入成功";
    }
   
}

function export(wrongDataList){
    //涉及stream模块
    wrongDataList.unshift(rowNameArray);// rowNameArray: 由列名组成的数组
    let buffer = xlsx.build(wrongDataList);// 获得buffer对象
    let passThroughStream = new stream.PassThrough();// 定义一个双向流
    passThroughStream.write(buffer);// 将buffer数据写入双向流
    return passThroughStream;
}

// controll层
const importFile = async ctx=>{
    await upload(ctx);

}

这样写完后,前端通过post请求上传文件,并在回调函数中接收到了stream流,但是不能自动下载。我就很疑惑了,为什么之前接触过的单独导出文件接口可以直接通过get请求方式,浏览器自动将文件流解析成文件并下载呢?

结论

经过一系列资料查询后并得出以下结论

1. 无论下载什么链接,异步ajax都无法直接下载,必须通过a标签或打开新窗口进行下载

   (PS:经过JS跳板群兄弟指导得出)

   (1) a标签设置download属性,可以直接下载普通链接能够访问的文件

   (2) 新窗口只能下载,响应头为Content-Type:application/octet-stream的文件

2. 后端将文件流返回给前端的时候,要设置请求头,并且文件名字不能使用中文。

       "Content-Disposition","attachment;filename=文件名字+文件类型"

3.在返回文件流的时候一定要在请求头带上文件流的字节长度(Content-Length)!!切记!切记!切记!

否则,前端要么下载文件失败,要么下载下来的文件无法打开。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值