簡體   English   中英

如何將 pdf 下載響應從 api(節點/快遞)傳送到客戶端(反應)?

[英]How to pipe a pdf download response from an api (node/express) to a client (react)?

在我的特定設置中,我有一個后端服務器,它生成一個 pdf,然后當訪問某個端點時,會觸發 pdf 下載。 但是,由於安全規則,我無法從前端訪問該端點,因此我需要使用中間人服務器向后端發出請求,並將其轉發給我的客戶端。

代碼:

前端(反應):

const axios = require('axios');
...
function getPDFDownload() {
    let opts = {
        url: `${middleman_root}/download`,
        method: "GET"
    };
    return axios(opts)
        .then((result) => {
            console.log(result);
            return result;
        }).catch((error) => {
            console.log(error);
            return error;
        })
}

中間人服務器(Node/express):

const request = require('request');
...
router.get("/download", (req, res) => {
    res.set("Content-Type", "application/pdf");
    res.set("Content-Disposition", "attachment; filename:file.pdf");
    let url = `${backend_root}/download`;
    request.get(url).pipe(res);
})

后端(節點/快遞):

router.get('/download', download);
...
const download = (req, res) => {
    ...
    return generatePDF()
        .then(({ filepath, filename }) => {
            res.download(filepath, filename);
        })
}

當單擊按鈕時調用前端函數getPDFDownload() ,然后將請求發送到中間人服務器,中間人服務器應該向后端服務器發送請求,並將響應通過管道返回到前端。

目前正在發生的事情:

似乎正在發送部分或全部 pdf,因為console.log(result)正在打印以下數據:

{
    "data": "%PDF-1.4↵%����↵1 0 obj↵<<↵/Type /Catalog↵/Version...",
    "headers": {
        "content-disposition": "attachment; filename=\"file.pdf\"",
        "content-type": "application/pdf",
        "content-length": "648748"
    },
    "status": 200
    ...
}

但是,該文件沒有被下載。 我知道有一個名為downloadjs的庫可以幫助解決這些問題,但是我想在不添加另一個庫的情況下解決這個問題,因為我不需要經常下載文件。

我試過的:

  • 將 API 生成的 PDF 發送到外部服務器?
  • res.sendFile() , res.end(fileData) , res.send({data: fileData})各種組合
  • 使用require('request-promise')而不是require('request')
  • res.download(filepath, filename)從后端代碼更改為:
fs.readFile(filepath, (err, data) => {
    if (err) throw err;
    const pdf = data.toString('base64');
    res.write(pdf, 'base64');
    // Since res.write would produce no result, I tried adding res.send() after res.write(), 
    // which achieved the same result, of pdf data being delivered, but not downloaded

    // Also tried replacing res.write(pdf, 'base64') with res.write(data, 'base64');
});
  • 安裝downloadjs並嘗試使用該包下載文件。 我的成功很小,因為下載了一個文件,並且它的長度正確,但 pdf 是空的。

前端代碼(修改):

import download from 'downloadjs';
...
function getPDFDownload() {
    ...
    return axios(opts)
        .then((result) => {
            download(result.data, "file.pdf", result.headers['content-type']);
        })
        .catch((error) => {
            console.log(error);
        })
}

在不情願地安裝了downloadjs之后,我終於讓它工作了 基本上我將前端代碼更改為如下所示:

import axios from 'axios';
import download from 'download';
...
function getPDFDownload() {
    let opts = {
        url: `${middleman_root}/download`,
        method: "GET",
        responseType: 'blob'
    };
    return axios(opts)
        .then((result) => {
            download(result.data, "file.pdf", result.headers['content-type']);
        }).catch((error) => {
            console.log(error);
        })
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM