Node (Express) - 通过 api 发送带有 express 的 pdf

Node (Express) - Send a pdf with express via an api

我有一个 api 可以为我网站上的每笔付款生成发票。另一方面,我有一台管理客户端的服务器。当客户要求时,我需要获取 pdf。

我正在使用 node/express 和 axios 来管理 http 调用。

我设法使用以下代码从 api 发送了 pdf:

function retrieveOneInvoice(req, res, next) {
    Order
        .findOne({_id: req.params.id, user: req.user.id})
        .exec((err, order) => {
            if(err) {

            } else if (!order) {
                res.status(404).json({success: false, message: 'Order not found!'});
            } else {
                const filename = order.invoice.path;
                let filepath = path.join(__dirname, '../../../invoices' ,filename);

                fs.readFile(filepath, function (err, data){
                    res.contentType("application/pdf");
                    res.end(data, 'binary');
                });
            }
        });
}

那部分工作正常,我可以获取并保存 pdf。此外,如果我打印数据,我会得到一个如下所示的缓冲区:<Buffer 25 50 44 46 2d 31 2e 34 0a 31 20 30 20 6f 62 6a 0a 3c 3c 0a 2f 54 69 74 6c 65 20 28 fe ff 29 0a 2f 43 72 65 61 74 6f 72 20 28 fe ff 29 0a 2f 50 72 6f ... >

在我的客户端上,我使用 axios 获取数据:

function retrieveInvoice(Config) {
    return function(orderId, done) {
        axios({
            url: `${Config.apiUrl}/invoices/${orderId}`,
            method: 'get'
        }).then(
            (res) => { return done(null, res.data) },
            (err) => { return done(err) }
        )
    }
}

最后我尝试通过调用前面的函数将它发送给客户端:

Api.retrieveInvoice(orderId, (err, data) => {
        if(err) {

        } else {
            res.contentType("application/pdf");
            res.end(new Buffer(data, 'binary'), 'binary');
        }
    });

这就是我遇到问题的地方。我总是收到空白页。我试过使用和不使用缓冲区,像这样:

res.contentType("application/pdf");
res.end(data, 'binary');

并且没有 'binary' 参数。如果我在 api 和我的客户端中记录数据,我得到完全相同的缓冲区和二进制文件。当我以完全相同的方式将它们发送给客户时,我只是不明白我的错误在哪里。

我希望我给了你足够的信息来帮助我,如果我缺少任何东西,我会添加所有可以帮助潜在帮手的东西。

感谢您的帮助。

你试过吗?

您的 axios 请求:

axios({
    url: `${Config.apiUrl}/invoices/${orderId}`,
    method: 'get',
    responseType: 'stream'
}).then(
    ...
)

你的回电:

Api.retrieveInvoice(orderId, (err, data) => {
    if (err) {
        // handle error
    } else {
        res.contentType("application/pdf");
        data.pipe(res);
    }
});

You can find documentation on this here.

默认的 responseType'json',所以改变这个应该可以解决问题。