使用Express

时间:2019-02-01 03:13:18

标签: javascript node.js http express

我在困难方面有独特的情况。

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

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

那么,是否可以将服务器上临时存储中的PDF文件发送到客户端,然后允许客户端代码对文件执行任何操作(对于我而言,是下载文件吗?)?

我不认为我必须提供任何代码,因为这更多是理论上的问题。

1 个答案:

答案 0 :(得分:0)

我的问题源于我不能仅从Express使用res.sendFile()res.download()的事实,因为该路由未被浏览器URL栏访问,而是我的应用程序使用了客户端路由,因此我不得不作出通过抓取或XMLHttpRequest的一个HTTP GET请求。

第二个问题是,我需要基于从客户端发送的HTML字符串在服务器上构建PDF文件-因此,我再次需要沿着请求正文发送GET请求。

我的溶液中,然后,使用取指,是使来自客户端的GET请求:

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

在服务器上,我有使用HTML-PDF节点模块将HTML字符串转换为PDF的代码,然后将文件转换为Base64字符串,设置了MIME类型并附加了{{1} }。

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('/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. }); 属性设置为Base64字符串,为其指定标题,然后以编程方式单击它:

href

所以,一起在客户端上

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

使用一个锚定标记来触发下载的溶液来自另一个StackOverflow的答案。还需要注意的是,Base64编码不是非常有效。存在更好的解决方案,但出于我的目的,Base64可以正常工作。

还必须注意,Base64编码恰好是-一种编码方案,不是,我重复一遍, not 是一种加密方案。因此,如果您的PDF文件包含特权信息,则可能要向端点添加令牌身份验证并加密文件。