Handling the response from `res.download()` on the client side (Rest api, express)

Issue

So the express docs have a download function in the following form:

res.download(cvUrl, cvName, function (err) {
  if (err) {
     // ...
  } else {
     // ...
  }
})

I think this would normally trigger the browser to download the file automatically, with the correct filename, as the response headers are correctly set and I’m receiving a file. But I’m handling the download like this:

this.admin.getCv(cvUrl).then(cv => {
    const url = window.URL.createObjectURL(new Blob([cv]));
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', 'test'); // how can I access the filename here?
    document.body.appendChild(link);
    link.click();
})

Is it possible to access the filename (cvName) on the frontend? Adding it as a second parameter seemed like the obvious solution, but didn’t work. Any hints would be great,

Thanks,

Nick

**Edit:

import JRS from '../api/jrs';

export default class Admin {
    getCv (applicantId) {
        return JRS.get(`/admin/cvs/${applicantId}`);
    }
}

// JRS.js

import axios from 'axios';

export default axios.create({
    baseURL: 'http://localhost:8080',
    headers: {
        'Content-Type':  'application/json',
    },
    withCredentials: true
});

Solution

The download method adds a Content-Disposition header to the response, so you just need to read that.

It looks like your getCv function makes an HTTP request, extracts the body from the response, then resolves a promise with that body.

You’ll need to modify the getCv function so it :

  • Reads the Content-Disposition header (how you do that depends on which HTTP API you are using)
  • Extracts the filename from it (something like contentDisposition.match(/filename=(.*)/))
  • Includes that in the data you are resolving the promise with (which will probably mean passing an object containing the filename and body instead of just the body)

Then you’ll need to change your then callback so it handles that object instead of expecting the body directly.


That said, it would probably be easier to just link to the URL directly instead of fetching the data with JSON, converting it to a data: URL, generating a link and triggering a client on it.

Answered By – Quentin

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published