【问题标题】:How to pipe a pdf download response from an api (node/express) to a client (react)?如何将 pdf 下载响应从 api (node/express) 传输到客户端 (react)?
【发布时间】:2020-09-23 22:57:43
【问题描述】:

在我的特定设置中,我有一个生成 pdf 的后端服务器,然后当访问某个端点时,触发 pdf 下载。但是,由于安全规则,我无法从前端访问该端点,因此我需要使用中间人服务器向后端发出请求,并将其转发给我的客户端。

代码:

前端(反应):

const axios = require('axios');
...
function getPDFDownload() {
    let opts = {
        url: `${middleman_root}/download`,
        method: "GET"
    };
    return axios(opts)
        .then((result) => {
            console.log(result);
            return result;
        }).catch((error) => {
            console.log(error);
            return error;
        })
}

中间人服务器(Node/express):

const request = require('request');
...
router.get("/download", (req, res) => {
    res.set("Content-Type", "application/pdf");
    res.set("Content-Disposition", "attachment; filename:file.pdf");
    let url = `${backend_root}/download`;
    request.get(url).pipe(res);
})

后端(节点/快递):

router.get('/download', download);
...
const download = (req, res) => {
    ...
    return generatePDF()
        .then(({ filepath, filename }) => {
            res.download(filepath, filename);
        })
}

点击按钮时调用前端函数getPDFDownload(),然后向中间人服务器发送请求,中间人服务器再向后端服务器发送请求,并将响应通过管道传回前端。

目前正在发生的事情:

似乎正在发送部分或全部 pdf,因为 console.log(result) 正在打印以下数据:

{
    "data": "%PDF-1.4↵%����↵1 0 obj↵<<↵/Type /Catalog↵/Version...",
    "headers": {
        "content-disposition": "attachment; filename=\"file.pdf\"",
        "content-type": "application/pdf",
        "content-length": "648748"
    },
    "status": 200
    ...
}

但是,文件没有被下载。我知道有一个名为 downloadjs 的库可以帮助解决这些问题,但我想在不添加另一个库的情况下解决这个问题,因为我不需要经常下载文件。

我尝试过的:

fs.readFile(filepath, (err, data) => {
    if (err) throw err;
    const pdf = data.toString('base64');
    res.write(pdf, 'base64');
    // Since res.write would produce no result, I tried adding res.send() after res.write(), 
    // which achieved the same result, of pdf data being delivered, but not downloaded

    // Also tried replacing res.write(pdf, 'base64') with res.write(data, 'base64');
});
  • 正在安装downloadjs 并尝试使用该软件包下载文件。我的成功很少,因为下载了一个文件,它的长度正确,但 pdf 是空的。

前端代码(修改):

import download from 'downloadjs';
...
function getPDFDownload() {
    ...
    return axios(opts)
        .then((result) => {
            download(result.data, "file.pdf", result.headers['content-type']);
        })
        .catch((error) => {
            console.log(error);
        })
}

【问题讨论】:

标签: javascript node.js reactjs express


【解决方案1】:

在不情愿地安装downloadjs 之后,我终于让它工作了 基本上我将前端代码更改为如下所示:

import axios from 'axios';
import download from 'download';
...
function getPDFDownload() {
    let opts = {
        url: `${middleman_root}/download`,
        method: "GET",
        responseType: 'blob'
    };
    return axios(opts)
        .then((result) => {
            download(result.data, "file.pdf", result.headers['content-type']);
        }).catch((error) => {
            console.log(error);
        })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 2021-03-09
    • 2020-03-15
    • 1970-01-01
    相关资源
    最近更新 更多