不为别的,只为做一个连自己都羡慕的人

node实现文件下载

1.方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
router.post('/downloadPdf',(req,res)=>{
    // let { filename,mimeType } = req.body;
    let { filename,mimeType } = req.query;
    // var path="public/pdf/5ea56710fb5a2fdad7cabcf3.pdf";
    // filename = '02cbc5d9-e10f-4f8d-8fae-304cc609a8f0';  //pdf
    // filename = '6f3db1f9-e247-4aa5-bca7-93bae62a0079' // mp4
    // filename = '6a908990-0c4f-4101-9e9d-4c8b00a8133b' // doc
    // filename='2055c73b-1b37-40bc-ba50-b6b8ef82e63c' // docx
    // mimeType='application/pdf';
 
    let type = getType(mimeType);  //获取文件后缀名
    console.log(filename,mimeType,type);
 
    // path = path.join(__dirname, '../public/showPdf/'+filename+'.'+type);
    path='./public/showPdf/'+filename+'.'+type;
    // path="C:\Users\sswc\Desktop\gai2\public\showPdf\02cbc5d9-e10f-4f8d-8fae-304cc609a8f0.pdf"
    console.log(path);
 
 
    var fileStream = fs.createReadStream(path);
    var size = fs.statSync(path).size;
    res.setHeader('Content-Type', mimeType);
    res.setHeader('Content-Disposition', `attachment;filename=${filename}.${type}`);
    res.setHeader('Content-Length', size);
    fileStream.on('data', function (data) {
        res.write(data, 'binary');
    });
    fileStream.on('end', function () {
        res.end();
        console.log('The file has been downloaded successfully!');
    });
     
})

 2.方法二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
router.post('/downloadPdf',(req,res)=>{
    // let { filename,mimeType } = req.body;
    let { filename,mimeType } = req.query;
    // var path="public/pdf/5ea56710fb5a2fdad7cabcf3.pdf";
    // filename = '02cbc5d9-e10f-4f8d-8fae-304cc609a8f0';  //pdf
    // filename = '6f3db1f9-e247-4aa5-bca7-93bae62a0079' // mp4
    // filename = '6a908990-0c4f-4101-9e9d-4c8b00a8133b' // doc
    // filename='2055c73b-1b37-40bc-ba50-b6b8ef82e63c' // docx
    // mimeType='application/pdf';
 
    let type = getType(mimeType);  //获取文件后缀名
    console.log(filename,mimeType,type);
 
    // path = path.join(__dirname, '../public/showPdf/'+filename+'.'+type);
    path='./public/showPdf/'+filename+'.'+type;
    // path="C:\Users\sswc\Desktop\gai2\public\showPdf\02cbc5d9-e10f-4f8d-8fae-304cc609a8f0.pdf"
    console.log(path);
 
 
    fs.readFile(path, (err, data) => {
        if (err) {
          throw err
        }
        res.setHeader('Content-Type',mimeType)
        // 设置文件名
        // Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件
        // attachment 以附件形式下载
        res.setHeader('Content-Disposition', `attachment; filename=${filename}.${type}`)
        // 返回数据
        res.end(data)
    })
 
})

上面两种通过node实现得下载代码得方式,获取文件路径需要通过相对路径,不能通过node提供得path取获取路径,如下所示:

1
path = path.join(__dirname, '../public/showPdf/'+filename+'.'+type);

在刚做文件下载时候,我是通过path来获取文件得路径,文件是可以下载得,但是只能下载一次,到第二次下载得时候,path获取路径得时候,会出现问题,导致接口包500得错误。当时耽搁了一整天,也没发现错在那里了,但是我写的下载接口就是只能调用一边,后面我看了看和其他人写的有什么不同,突然间看见是因为path得原因。当我的path通过相对路径获取得时候,下载接口恢复了正常。 

注意:我这里得getType()方法是用来获取文件得后缀名得,因为当时我们做得时候,平台支持得文件有很多种形式,为了做各种文件得下载兼容以及更好得取寻找我们需要对应得文件,所以定义了一个方法,用来兼容各种类型得文件,该方法如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 获取文件得后缀名
function getType(mimeType){
    switch(mimeType) {
        case 'video/x-msvideo'return 'avi';
        case 'video/x-ms-wmv': return 'wmv';
        case 'video/x-flv': return 'flv';
        case 'image/x-ico': return 'ico';
        case 'image/x-psd': return 'psd';
        case 'text/csv': return 'csv';
        case 'text/html': return 'html';
        case 'text/plain': return 'txt';
        case 'text/xml': return 'xml';
        case 'video/mp4': return 'mp4';
        case 'video/mpeg': return 'mpg';
        case 'application/x-shockwave-flash': return 'swf';
        case 'audio/mpeg': return 'mp3';
        case 'audio/x-ogg': return 'ogg';
        case 'audio/x-wav': return 'wav';
        case 'image/jpeg': return 'jpg';
        case 'image/png': return 'png';
        case 'image/svg+xml': return 'svg';
        case 'application/x-mspublisher': return 'pub';
        case 'application/vnd.visio': return 'vsd';
        case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': return 'docx';
        case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': return 'xlsx';
        case 'application/vnd.openxmlformats-officedocument.presentationml.presentation': return 'pptx';
        case 'application/msword': return 'doc';
        case 'application/pdf': return 'pdf';
        case 'application/postscript': return 'ps';
        case 'application/rtf': return 'rtf';
        case 'application/vnd.ms-access': return 'mdb';
        case 'application/vnd.ms-excel': return 'xls';
        case 'application/vnd.ms-powerpoint': return 'ppt';
        case 'application/vnd.oasis.opendocument.text': return 'ott';
    }
}

  

  

posted @   升级打怪  阅读(2004)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示