簡體   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