Express res.download()

Viewed 20317

I don't know why it's happening, but it's really annoying. I expected the file to be downloaded according to the express docs. I have the next code:

  //in react (App.js)
  download = () => {
    const { images, target } = this.state;
    const filename = images.find(img => img.id === target).filename;
    fetch('http://localhost:3001/download', {
      method: 'post',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({filename})
    })
  }
  //in express (server.js)
  app.post('/download', (req, res) => {
    var file = '../public/images/' + req.body.filename;
    res.download(file, req.body.filename);
  });

The folder structure:

  -server
    |-server.js
  -public
    |-images
      |-a.jpg
      |-b.jpg
  -src
    |-App.js

Nothing's happening, errors not shown. Any ideas?

3 Answers

I think the issue you have is that you're using an HTTP POST instead of HTTP GET

It was a challenge, but this worked for me.

    const express = require('express');
    const path = require('path');
    const port = process.env.PORT || process.argv[2] || 8080;
    const app = express();
 
    app.get('/', (req, res)=>{
      res.send('<a href="/download">Download</a>');
    });
 
    app.get('/download', (req, res)=>{
      res.download(path.join(__dirname, 'views/files.pug'), (err)=>{
        console.log(err);
      });
      console.log('Your file has been downloaded!')
    });
 
    app.listen(port, ()=>{
      console.log('res is up on port: ' + port);
    });

Just replace the file names with yours.

The download method sets the Content-Disposition header which tells the browser to download it instead of navigating to it … if it were navigating to it in the first place.

You are making the request using Ajax, so the browser isn't navigating to it. The response is passed to your JS and it is the responsibility of your JS to deal with it.

You can take two approaches to this:

Related