簡體   English   中英

由 response.download() 響應的文件並下載為包含未定義的 blob

[英]File responsed by response.download() and download as blob containing undefined

我正在構建一個客戶端-服務器證書生成器。


后端我使用兩個端點:

/
  • 接收包含從輸入中提取的數據的 JSON,對其進行清理,並返回它們是否有效
/download
  • 接收數據是否有效。 如果是,則生成一個certificate.pdf文件並使用res.download(certificatePath)響應它
  • 我想我應該使用某種令牌/身份驗證/授權,因為有人可以忽略第一個端點,但是一旦下載本身被修復,我就會這樣做

我認為后端的問題在於其中一些功能:

const getCertificatePDF = (name, validValuesData, validValuesQty, response) => {
    // ... ommited for brevity
    pdf.create(document, options)
        .then(res => {
            console.log(res)
            let filePath = path.join(__dirname, 'certificate.pdf');
            console.log("FILE PATH: ", filePath);                            
            response.download(filePath, "certificate.pdf");
        })
        .catch(error => {
            console.error(error)
        });
}

app.post('/download', (req, res) => {
    const data = req.body;
    console.log("DATA", data);
    getCertificatePDF(data.name, data.validValuesData, data.validValuesQty, res)
});

前端,我使用 Promise 鏈接了兩個申請,創建了一個blob ,為該blob創建了一個帶有download屬性的鏈接並觸發了onClick

const sendForm = (filledCodeValues, email, name) =>{
    // ...ommited for brevity

    fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: data,
      })
        .then((res) => res.json())
        .then((processedData) => {
            alertAllFilledInvalid(processedData.validValuesQty)
            const dataString = JSON.stringify(processedData);
            if(processedData.validValuesQty > 0){
                console.log("DATA STRING ", dataString)
                const downloadUrl = url + "download";
                fetch(downloadUrl, {
                    method: "POST",
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: dataString,
                  })
                .then((res2) => {
                    res2.blob()
                })
                .then((blob)=>{
                    const newBlob = new Blob([blob]);
                    const newUrl = window.URL.createObjectURL(newBlob);

                    const link = document.createElement('a');
                    link.href = newUrl;
                    link.setAttribute('download', 'certificate.pdf');
                    document.body.appendChild(link);
                    link.click();
                    link.parentNode.removeChild(link);

                    window.URL.revokeObjectURL(newBlob);
                })
            }
        })
}

問題

問題是,前端下載的certificate.pdf包含undefined前端下載的未定義證書

我知道第一個請求是正確的,因為console.log()正在打印stringData的預期內容:

前端設法完成第一個請求

我也知道第二個請求有效,因為在后端,certificate.pdf 正在正確生成

后端正確接收第二次申請並生成pdf

Ps - 我在后端手動刪除certificate.pdf以確保它是一個新生成的

由於正在生成證書,我認為其中任何一個都有問題:

  1. 后端的response.download(filePath, "certificate.pdf");
  2. 前端 blob 創建和下載

我手動將certificate(25).pdf (由前端生成)移動到后端並運行一個腳本來讀取兩個certificate.pdf (由后端生成)文件,以使用readFiles.js腳本測試問題是否在filePath上:

const fs = require('fs');
let path = require('path');

let filePath = path.join(__dirname, 'certificate.pdf');
console.log("FILE PATH: ", filePath);
fs.readFile(filePath, 'utf8', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log(">>>>> FilePath content <<<<< ", data);
});


let filePath2 = path.join(__dirname, 'certificate(25).pdf');
console.log("FILE PATH 2: ", filePath2);
fs.readFile(filePath2, 'utf8', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log(">>>> FilePath2 content <<<< ", data);
});

讀取文件

事實證明路徑是正確的,並且certificate.pdf (backend)有內容,而certificate(25).pdf (frontend)只有一個undefined的值。


有人能幫助我嗎?

您需要返回res2.blob()的值:

.then((res2) => {
  return res2.blob()
})

或者省略括號:

.then((res2) => res2.blob())

暫無
暫無

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

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