繁体   English   中英

使用Express从Node.js向客户端发送文件

[英]Sending a file to the client from Node.js with Express

就困难而言,我有一个独特的处境。

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

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

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

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

我的问题源于以下事实:我不能仅使用Express的res.sendFile()res.download() ,因为浏览器URL栏未访问该路由,而是我的应用程序使用了客户端路由,因此我必须通过Fetch或XMLHttpRequest发出HTTP GET请求。

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

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

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 String,为其指定标题,然后以编程方式单击它:

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文件包含特权信息,则您可能希望向端点添加令牌认证并加密文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM