ReactJS download file from Express Server
Your request to postman will work because I assume you are hitting the correct endpoint which is '/getdoc' which will let you download the pdf via postman.
However, your fetch request does not seem to match the API endpoint that serves the pdf document. That is why your React Component will give you the error on download.
const handleDownload = async () => {
const res = await fetch("http://localhost:3001/download");
const blob = await res.blob();
download(blob, "test.pdf");
}
//the fetch call for "http://localhost:3001/download" will not hit '/getdoc'
app.get('/getdoc', function (req, res) {
res.download(path.join(__dirname, 'files/test.pdf'), function (err) {
console.log(err);
});
});
Here is how I implemented the pdf download.
//resume route... this route is hit when you make a GET request to /api/resume
const router = require('express').Router();
module.exports = router;
//when route is hit the resume is downloaded
//aka /api/resume
router.get('/', (req, res, next) => {
try {
const file = `${__dirname}/resume/resume.pdf`;
res.download(file);
console.log('here');
} catch (err) {
console.log(err);
}
});
//react component
import React from 'react';
import download from 'downloadjs';
const Resume = () => {
return (
<div>
<button
type="button"
onClick={async () => {
const res = await fetch('/api/resume');
const blob = await res.blob();
download(blob, 'test.pdf');
}}
>
Download
</button>
</div>
);
};
Related videos on Youtube
Patrick.H
Updated on June 04, 2022Comments
-
Patrick.H almost 2 years
I'm trying to make my user able to download a file from our backend server. I've tried the solution from this question as well as the backend from this.
Sadly none of them worked. The download itself works through postman, but not in react.
Additional info: The Backend is running on the same machine but on port 3001 while the frontend is running on port 3000 I'm not sure if that helps, but the react frontend is connected to the backend via proxy in the package.json
"proxy": "http://localhost:3001",
The client side currently looks like this:
const download = require("downloadjs"); const handleDownload = async () => { const res = await fetch("http://localhost:3001/download"); const blob = await res.blob(); download(blob, "test.pdf"); } function App() { return ( <div className="App"> <header className="App-header"> <button onClick={() => handleDownload().finally(() => console.log("Passed through the whole handleDownload Request"))}> </button> </header> </div> ); }
while on the backend side I'm using this code as from the previous questions asked here on stackoverflow.
app.get('/getdoc', function (req, res) { res.download(path.join(__dirname, 'files/test.pdf'), function (err) { console.log(err); }); });
This is the Code working through Postman, but it won't trigger a download in React.
The Error occurring in react looks like this:
App.js:8 GET http://localhost:3001/download/test.pdf net::ERR_CONNECTION_REFUSED Uncaught (in promise) TypeError: Failed to fetch
So it seems the handling on frontend seems to be the problem, as it is not triggering the Save Dialog from the browser (Chrome).
-
Patrick.H almost 5 yearsI still get the Err: App.js:7 GET localhost:3001/download net::ERR_CONNECTION_REFUSED which is the line of: reqObj.open('GET',...); and status code = 0
-
mattemyo almost 5 yearscould you try to access localhost:3001/download directly in the url bar of your browser?
-
Patrick.H almost 5 yearsIt responds with the same error, that's the strange thing... In Postman I can download the file without any problems
-
mattemyo almost 5 yearsor maybe you would have to specify the headers of the fetch
-
Patrick.H almost 5 yearsyes i have and I still get the ERR_CONNECTION_REFUSED message. I wouldn't know which headers to set, since this is a simple get request
-
Sanket about 2 yearsIs it possible to download the file without using the "download" module ?
-
Queens Coder about 2 yearsof course, there are a ton of packages you can use, or you could do it without one. the easiest way to download a file would be to create a link with the URL to the file and include that in your HTML/React/Frontend