【问题标题】:Node (Express) - Send a pdf with express via an apiNode (Express) - 通过 api 发送带有 express 的 pdf
【发布时间】:2017-11-23 04:57:27
【问题描述】:

我有一个 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 和我的客户端中记录数据,我会得到完全相同的缓冲区和二进制文件。当我以完全相同的方式将它们发送给客户时,我无法理解我的错误在哪里。

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

感谢您的帮助。

【问题讨论】:

    标签: node.js api express pdf axios


    【解决方案1】:

    你试过了吗?

    你的 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',因此更改此设置应该可以解决问题。

    【讨论】:

    • 非常感谢,我之前尝试过data.pipe(res),但我没有看到响应类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    相关资源
    最近更新 更多