Reputation: 117
In my specific setup, I have a backend server which generates a pdf, and then when a certain endpoint is visited, the pdf download is triggered. However, due to security rules, I cannot access that endpoint from my frontend, so I need to use a middle-man server to make the request to the backend, and forward it to my client.
Frontend (React):
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;
})
}
Middle-man server (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);
})
Backend (Node/express):
router.get('/download', download);
...
const download = (req, res) => {
...
return generatePDF()
.then(({ filepath, filename }) => {
res.download(filepath, filename);
})
}
The frontend function getPDFDownload()
is called when a button is clicked, which then sends a request to the middleman server, which should then send a request to the backend server, and pipe the response back to the frontend.
It seems that either some or all of the pdf is being sent, since the console.log(result)
is printing the following data:
{
"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
...
}
However, the file is not being downloaded. I know that there exists a library called downloadjs
which helps with these problems, but I would like to solve this without adding another library since I don't need to download files often.
res.sendFile()
, res.end(fileData)
, res.send({data: fileData})
require('request-promise')
instead of require('request')
res.download(filepath, filename)
from the backend code to: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
and trying to use that package to download the file. I have minimal success, in that a file is downloaded, and it is of the correct length, but the pdf is empty.Frontend code (modified):
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);
})
}
Upvotes: 2
Views: 2803
Reputation: 117
I finally got it to work, after reluctantly installing downloadjs
Basically I changed my frontend code to look like this:
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);
})
}
Upvotes: 2