前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用nodejs做文件下载中转

使用nodejs做文件下载中转

作者头像
OECOM
发布2020-07-02 11:46:37
3.3K0
发布2020-07-02 11:46:37
举报
文章被收录于专栏:OECOMOECOM

之前做了一个功能就是点击按钮实现文件下载,文件保存在了阿里云的OSS上,阿里的OSS和七牛的OSS其实个人感觉差不多,一般情况下,前端下载文件很多都是通过一个a标签来进行下载。但是对于OSS存储的文件比如图片点击后在浏览器直接打开了,即使是添加了download属性也无济于事,于是我就想到了使用nodejs来搭建一个中转站。

我们先来直接看一下示例代码,然后再进行说明:

代码语言:javascript
复制
router.get('/downloadFile',function(req,res){
    try{
        let filePath = req.query.filePath;
        let fileName = req.query.fileName;
        let imgProtocol = filePath.slice(0,filePath.indexOf(":"));
        let imgName = fileName||filePath.slice(filePath.lastIndexOf("/")+1);
        if(imgProtocol==='https'){
            https.get(filePath,function(imgReq,imgRes){  //path为网络文件地址
                var fileSize = imgReq.headers["content-length"];
                imgReq.setEncoding('binary');
                res.setHeader("Content-Type", "application/octet-stream");
                res.setHeader("content-length",fileSize);
                res.setHeader("Content-Disposition", "attachment; filename="+encodeURI(imgName));
                res.setTimeout(30*60*1000)
                imgReq.on('data',function(chunk){
                    res.write(chunk,"binary"); //格式必须为 binary,否则会出错
                })
                imgReq.on('end',function(){
                    console.log("文件下载完毕");
                    res.end()
                })
            })
        }else{
            http.get(filePath,function(imgReq,imgRes){  //path为网络文件地址
                var fileSize = imgReq.headers["content-length"];
                imgReq.setEncoding('binary');
                res.setHeader("Content-Type", "application/octet-stream");
                res.setHeader("content-length",fileSize);
                res.setHeader("Content-Disposition", "attachment; filename="+encodeURI(imgName));
                res.setTimeout(30*60*1000)
                imgReq.on('data',function(chunk){
                    res.write(chunk,"binary"); //格式必须为 binary,否则会出错
                })
                imgReq.on('end',function(){
                    console.log("文件下载完毕");
                    res.end()
                })
            })
        }
    }catch(e){
        res.end(JSON.stringify({success: false, msg: e.stack}));
    }

})

从上面的代码中我们可以看到,接口接收的参数有两个,一个是文件名,一个是文件路径,如果没有文件名我们就默认文件路径的最后一个斜杠后面就是文件名了。接下来要做的就是区分文件存储的环境是https还是http,两种方式没有什么别的区别,只是请求的模块不一样,当然这里我们也可以使用request模块,不在多说。当get请求有响应后,我们开始做向客户端返回数据的准备。

如上面代码中所示,我们获取了content-length,来告诉客户端浏览器将要下载的文件总大小是多少。然后设置文件的编码为binary,也就是二进制的格式,为什么要设置成二进制呢?是因为我们不知道即将下载的文件格式具体是什么。所以我们也将Content-Type的内容设置成了application/octet-stream。随后设置的就是文件大小和Content-Disposition,在这里我们对filename进行了url转码,是因为如果直接使用中文,在这里会报错的。

再后面我们设置了一个超时时间为30分钟,因为nodejs默认的接口超时时间为2分钟,这对于下载一些大文件来说很不现实。我设置30分钟是因为这里文件的大小不超过200M,30分钟足矣下载完成,当然,你也可以设置为setTimeout(0),使其超时时间不做限制。

随后当请求返回数据后,我们也将数据写入到接口的响应体中,同时编码格式也是二进制。直到流获取完成,此时也将数据全部都写入到了响应体中,之后调用res.end来结束连接。

如此,一个使用nodejs来作为文件下载中转的例子就写好了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-01-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档