Issue with image download using node

Viewed 58

I am trying to download an image .I have been able to successfully store an image in my folder on server and the image details in my mongodb collection . I want to download the image when user clicks on download button on the frontEnd . I have added a route on my backend side which works well here it is my localhost is 8080....

    app.get('/download/', function(req, res){
      var file ='./uploads/2021-08-14T08-07-50.126Z-sample.pdf';
      var filename = path.basename(file);
      var mimetype = mime.lookup(file);
      res.setHeader('Content-disposition', 'attachment; filename=' + filename);
      res.setHeader('Content-type', mimetype);
      var filestream = fs.createReadStream(file);
      filestream.pipe(res);
       }); 

Below is a screenshot of front end

enter image description here

Above file data is dynamic I am getting it from my backend using fetch.

Now what I want is when when a download button is clicked I want to append the file name in the url parameter for example....

fetch(localhost:8080/download/${file.name},{method:"GET"})

so that I can use the passed variable in the parameter to download the selected file which has been selected by the user in the front end.

For example:

  app.get('/download/', function(req, res){
  var file =`./uploads/${req.params.filename}`;
  var filename = path.basename(file);
  var mimetype = mime.lookup(file);
  res.setHeader('Content-disposition', 'attachment; filename=' + filename);
  res.setHeader('Content-type', mimetype);
  var filestream = fs.createReadStream(file);
  filestream.pipe(res);
   });

The solution I get which is working in my frontend is

function download(name) {
 return fetch(`http://localhost:8080/download/${name}`,{method:"GET",})
  .then(res => res.blob())
    .then( blob => {
      const file = window.URL.createObjectURL(blob);
      window.location.assign(file);
  });
 }
1 Answers

If you're using express, something like this should work.


app.get('/download/:filename', function(req, res){
  var file =`./uploads/${req.params.filename}`;
  var filename = path.basename(file);
  var mimetype = mime.lookup(file);
  res.setHeader('Content-disposition', 'attachment; filename=' + filename);
  res.setHeader('Content-type', mimetype);
  var filestream = fs.createReadStream(file);
  filestream.pipe(res);
});

I also advise you to use const instead of var, because none of these variables are being used outside scope and are not being reasigned


app.get('/download/:filename', function(req, res){
  const file =`./uploads/${req.params.filename}`;
  const filename = path.basename(file);
  const mimetype = mime.lookup(file);
  res.setHeader('Content-disposition', 'attachment; filename=' + filename);
  res.setHeader('Content-type', mimetype);
  const filestream = fs.createReadStream(file);
  filestream.pipe(res);
});

For the problem with fetch you having you can use this code:


const file = filename.split(".")
const mime = file[file.length - 1] // get the last index

  fetch(url, {
    method: 'POST',
    mode: 'no-cors',
    cache: 'no-cache',
    headers: {
      'Content-Type': `image/${mime}`
    },
    referrerPolicy: 'no-referrer'
  }).then((image) => {

    const imageBlog = await image.blob()
    const imageURL = URL.createObjectURL(imageBlog)

    const link = document.createElement('a')
    link.href = imageURL

    link.download = 'image file name here'
    document.body.appendChild(link)

    link.click()
    document.body.removeChild(link)

  });

Test it and tell me if it works, change the variable names too

Related