ReactJS download file from Express Server

10,300

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>
  );
};
Share:
10,300

Related videos on Youtube

Patrick.H
Author by

Patrick.H

Updated on June 04, 2022

Comments

  • Patrick.H
    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
    Patrick.H almost 5 years
    I 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
    mattemyo almost 5 years
    could you try to access localhost:3001/download directly in the url bar of your browser?
  • Patrick.H
    Patrick.H almost 5 years
    It responds with the same error, that's the strange thing... In Postman I can download the file without any problems
  • mattemyo
    mattemyo almost 5 years
    or maybe you would have to specify the headers of the fetch
  • Patrick.H
    Patrick.H almost 5 years
    yes 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
    Sanket about 2 years
    Is it possible to download the file without using the "download" module ?
  • Queens Coder
    Queens Coder about 2 years
    of 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