6

I have a request that is supposed to download a file from remote api. What I want is, however, to save this file with the same name which it is saved with when I download the file from browser. For example, I have an URL https://myapi.com/files/4hjiguo4ho45946794526975429, and when I click this link, browser immediately starts to download a file from that URL with name myfile20180601.txt. How do I save the file with the same name if I make a request from Node.js? This is my code:

axios({
    method: 'get',
    url: 'https://myapi.com/files/4hjiguo4ho45946794526975429',
    responseType: 'stream',
    headers: {
        Authorization: 'Basic KJVEB46287blablablatoken'
    }
})
 .then(res => res.data.pipe(fs.createWriteStream(`${/* filename */}.txt`)))
 .catch(err => console.error(err));
AlexNikolaev94
  • 1,169
  • 2
  • 16
  • 40
  • The filename should be in the response headers. Try to look into `res` for it. I don't know `axios` ... – eisbehr Jun 01 '18 at 11:10
  • Look for the `content-disposition` header (see [axios docs](https://github.com/axios/axios#response-schema)) in the `res.headers` object, and grab the `filename="myfile20180601"` part of the value. – Sven Jun 01 '18 at 11:31

4 Answers4

16

You can find your filename in the response of axios

    var axios = require('axios')
    var fs = require('fs')

    axios({
        method:'get',
            url:'https://myapi.com/files/4hjiguo4ho45946794526975429',
            responseType:'stream'
        })
    .then(function(response) {
-       let headerLine = response.data.headers['content-disposition'];
+       let headerLine = response.headers['Content-Disposition'];
        let startFileNameIndex = headerLine.indexOf('"') + 1
        let endFileNameIndex = headerLine.lastIndexOf('"');
        let filename = headerLine.substring(startFileNameIndex, endFileNameIndex);
        response.data.pipe(fs.createWriteStream(filename));
    });

Hope this response helped you

Community
  • 1
  • 1
boubaks
  • 352
  • 2
  • 8
9

I believe this will help!

let filename = response.headers['content-disposition'].split('filename=')[1].split('.')[0];
let extension = response.headers['content-disposition'].split('.')[1].split(';')[0];

console.log(`${filename}.${extension}`)
Agostinho Tinho
  • 129
  • 1
  • 3
1

For me it was better to use the regular expression, more reliable.

const match = response.headers['content-disposition'].match(/filename="([^"]+)"/);

// match[1] that's filename
-3

It has already been answered for backend, here i'm posting the answer for frontend.

You can get the browsed file name in by accessing the event --> event.target.files[0].name

Ex:

onChange={(event) => {
  const fileName = event.target.files[0].name;
  console.log('fileName', fileName);
}}
Sangeeth
  • 335
  • 3
  • 13