Express.JS response.download未下载文件



我正在处理一个节点。JS服务器使用Express根据用户输入生成和下载PDF。我使用Axios POST调用服务器,然后期望使用来自Express的response.download((下载文件。我最近从使用<form action="">方法调用API改为使用Axios,因为Netlify似乎不支持NuxtAPI。该程序在旧版本中生成了所需的文件,但Axios的更改意味着它不再工作。

现在,没有文件被下载(即使是固定路径的文件,比如在发布的网站上(,页面甚至在被提示下载之前就已经重新加载了。

我的代码如下:

print.vue:


<template>
<main>
<button class="btn btn-primary" @click="submit">Print Certificate</button>
</main>
</template>
<script>
export default{
methods:{
async submit(){
try{
let params = {
name: this.name,
kana: this.kana,
rank: this.rank,
date: this.date
}
// produces valid object in all cases
await this.$axios.$post('/api/certificate', null, {params})
}catch(err){
console.log(err)
alert(err)
}
}
},
computed:{ // functions from route params, resolve to these always for test case
name: function(){return 'Test Student'},
kana: function(){return "Tesuto Sutuudento"},
rank: function(){return "8th Kyu"},
date: function(){return '26th October, 2020"}
}
}
</script>

/api/certificate.js

var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.post('/', urlencodedParser, function(req, res) {
let response = {
name: req.query.name,
kana: req.query.kana,
rank: req.query.rank,
date: req.query.date
}
console.log(response)
html = html.replace("{{name}}", response.name)
html = html.replace("{{kana}}", response.kana)
html = html.replace("{{rank}}", response.rank)
html = html.replace("{{date}}", response.date) // always produces valid string (template)
pdf.create(html, options).toFile('static/certificates/' + response.name.split(' ')[0] + '_' + response.rank.split(' ')[0] + '_' + response.rank.split(' ')[1] + '.pdf', function(err, rep){
// file made with no difficulties
if (err) return console.log(err);
console.log(rep.filename) // gives absolute path (C:\)
//res.download('https://get.pxhere.com/photo/computer-screen-technology-web-internet-signage-page-coding-website-html-programming-font-design-text-digital-information-java-site-games-software-development-code-screenshot-data-script-www-css-computer-programming-web-developer-web-development-programming-code-web-page-website-development-670370.jpg') // test fixed path downloading
//res.download(rep.filename,'my_pdf.pdf') // what I think the easiest solution should be
res.download('static/certificates/' + response.name.split(' ')[0] 
+ '_' + response.rank.split(' ')[0] + '_' 
+ response.rank.split(' ')[1] + '.pdf') // what worked before
})
})

一般来说,我对API和Node还比较陌生,所以我缺少一些基本的东西吗?

事实证明,Axios除了TXT、HTML或JSON文件外,不喜欢下载任何东西,所以我们需要将生成的文件下载为数组缓冲区,然后使用js文件下载将其转换为我们想要的文件格式。

以下示例:

在我的服务器中

import Path from 'path'
import pdf from 'html-pdf'
pdf.create(html, options).toFile('./mypdf.pdf', function(err, rep){
if (err) return console.log(err);
let path = Path.resolve(rep.filename) // ensures we always get the generated path
console.log("resoved path:" + path)
res.setHeader('Content-disposition', 'mypdf.pdf');
res.download(path)
})

在我的客户:

methods:{
async submit(){
const fileDownloader = require('js-file-download');
try{
let params = {
name: this.name,
kana: this.kana,
rank: this.rank,
date: this.date
}
// use responseType to tell axios its a buffer, using $post instead of post is shorthand for post().data
// not setting this header results in corrupted pdfs
let response = await this.$axios.$post('/api/certificate', null, {params: params, responseType:'arraybuffer'})
console.log(response) // gibberish because Adobe
// create and immediately download. Since we don't want to give a choice, immediate download is fine 
fileDownloader(response, 'mypdf.pdf') 

}catch(err){
console.log(err)
alert(err)
}
}
},

特别感谢这个针对客户端标头的答案,这个针对js文件下载器链接的答案,以及这个针对服务器端响应标头的答案。没想到会这么棘手。

我认为这将适用于

了解有关writeFileSync 的更多信息


const data = {
Patient_name: result.patient_name,
Doctor: result.doctor,
Date: result.date,
Time: result.time,
Key: result.key
};
const path = `${process.cwd()}/public/UserData.csv`;
fs.writeFile(path, data, function (err) {
if (err) { throw err; }
else {
res.download(path);
console.log(data);
}
})

最新更新