response.download() 响应的文件并下载为包含未定义的 blob

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

我正在构建客户端-服务器证书生成器。


后端 我正在使用两个端点:

/
/download

我认为后端的问题出在其中一些函数中:

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)
});

前端,我使用 promises 链接了两个请求,创建了一个 blob,创建了一个具有 download 属性的 link blob 并触发了 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 被正确生成:

Ps - 我正在后端手动删除 certificate.pdf 以确保它是新生成的

由于正在生成证书,我认为两者都有问题:

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

我手动将 certificate(25).pdf(由前端生成)移动到后端和 运行 一个用于读取两个 certificate.pdf(由后端生成)文件的脚本,以测试问题是否存在filePath 使用 readFiles.js 脚本:

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值。


有人可以帮我吗?

您需要 return res2.blob() 的值:

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

或省略括号:

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