【问题标题】:Sending a file to the client from Node.js with Express使用 Express 从 Node.js 向客户端发送文件
【发布时间】:2019-02-01 03:13:18
【问题描述】:

在难度方面我有一个独特的情况。

我需要将 HTML 发送到服务器,让服务器将 HTML 转换为 PDF,将该 PDF 发送回客户端,然后使用 客户端代码下载 PDF。 p>

我必须这样做,因为我使用的是客户端路由,所以我可以访问应该执行此操作的端点的唯一方法是通过 Ajax 的 GET 请求或从客户端 JavaScript 获取。我知道res.sendFile(),但它试图在浏览器中呈现文件 - 我不希望这样 - 相反,我希望能够使用客户端代码来下载文件。

那么,是否有可能将 PDF 文件从服务器上的临时存储发送到客户端,从而允许客户端代码在此后对文件执行任何操作 - 就我而言,下载它?

我认为我不必提供任何代码,因为这更像是一个理论问题。

【问题讨论】:

标签: javascript node.js http express


【解决方案1】:

我的问题源于这样一个事实,即我不能只使用 Express 中的 res.sendFile()res.download(),因为浏览器 URL 栏没有访问路由,而是我的应用程序使用客户端路由,因此我必须通过 Fetch 或 XMLHttpRequest 发出 HTTP GET 请求。

第二个问题是我需要根据从客户端发送的 HTML 字符串在服务器上构建 PDF 文件 - 所以我需要再次发送请求正文的 GET 请求。

然后,我使用 Fetch 的解决方案是从客户端发出 Get 请求:

fetch('/route' , {
    method: 'GET',
    body: 'My HTML String'
});

在服务器上,我的代码使用 HTML-PDF 节点模块将 HTML 字符串转换为 PDF,然后我将该文件转换为 Base64 字符串,设置 MIME 类型并附加 data:application/pdf;base64,

app.get('/route', (req, res) => {
    // Use req.body to build and save PDF to temp storage (os.tempdir())
    // ...
    fs.readFile('./myPDF.pdf', (err, data) => {
        if (err) res.status(500).send(err);
        res.contentType('application/pdf')
           .send(`data:application/pdf;base64,${new Buffer.from(data).toString('base64')}`);
    });
});

回到客户端,我收到了前面提到的 Fetch Request,这意味着我只需要兑现承诺即可获得响应:

fetch('/route', {
    method: 'POST',
    body: 'My HTML String' // Would define object and stringify.
})
.then(res => res.text())
.then(base64String => {
    // Now I just need to download the base64String as a PDF.
});

为了进行下载,我动态创建了一个锚标记,将其href 属性设置为来自服务器的响应中的 Base64 字符串,给它一个标题,然后以编程方式单击它:

const anchorTag = document.createElement('a');
anchorTag.href = base64String;
anchorTag.download = "My PDF File.pdf"; 
anchorTag.click();

所以,大家一起在客户端:

fetch('/route', {
    method: 'POST',
    body: 'My HTML String' // Would define object and stringify.
})
.then(res => res.text())
.then(base64String => {
    const anchorTag = document.createElement('a');
    anchorTag.href = base64String;
    anchorTag.download = "My PDF File.pdf"; 
    anchorTag.click();
});

使用锚标记触发下载的解决方案来自另一个 StackOverflow 答案。同样重要的是要注意 Base64 编码不是很有效。存在更好的解决方案,但就我而言,Base64 可以正常工作。

还必须注意 Base64 编码正是 - 一个编码方案,不是,我重复一遍,不是一个加密方案。因此,如果您的 PDF 文件包含特权信息,您可能希望将令牌身份验证添加到端点并加密文件。

【讨论】:

    猜你喜欢
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多