0

I am building an image compressor using node and react. The server sends the client the image by res.download(filepath), but in the client the doesn't happen. But I get the 200 OK response in the network and the image attachment. How can I trigger download in the client automatically?

Here is my the express router that handles image compression and download code:

app.get('/download/:imageName', async (req,res)=>{
let imageName = req.params.imageName
let path = 'uploads/'+imageName;

//Image compression code
const compressedImage = await imagemin([path], {
    destination: "output",
    plugins: [
      imageminPngquant({
        quality: [0.6, 0.8]
      }),
      imageminMozjpeg(),
      imageminGifsicle({lossy: 70}),
      imageminSvgo({
        plugins: extendDefaultPlugins([
            {name: 'removeViewBox', active: false}
        ])
        })
    ]
  });
  // Here filepath = process.cwd()+"/"+compressedImage[0].destinationPath
  res.download(process.cwd()+"/"+compressedImage[0].destinationPath)
})

Here is my client-side function which sends get request for downloading the image:

  function downloadAnImage(imageLink){
 fetch("/download/"+imageLink)
}

By the way, I didn't handle the response on the client-side because the download should happen after getting the response.

But If the type the full image URL path in the browser the download happens. Then I thought I should send the full image URL to the client but I couldn't find a to get the host URL that my server is running. I know the URL my server is running but Since I am gonna host this app, manually putting "localhost:3001" as the host url is not gonna work, right?

  • You cannot use fetch() to trigger a download. Just do `location = "/download/" + imageLink` instead, and the browser will start the download. –  May 21 '21 at 11:57
  • Can you please elaborate on your answer? Is location is a variable? – Iftekhar Riyad May 21 '21 at 13:19
  • No, it's `window.location`. By setting it to a different URL you tell the browser to navigate there, or, if the URL leads to something sent with a `content-disposition: attachment` header, trigger a download. You should be able to use the line as-is in place of your fetch() command. –  May 21 '21 at 15:11
  • Yes, this is basically a duplicate of https://stackoverflow.com/questions/11620698/how-to-trigger-a-file-download-when-clicking-an-html-button-or-javascript but did you try my proposed solution? Did it not work? (it absolutely works for me: https://jsfiddle.net/0kve21jw/) –  May 22 '21 at 08:22
  • 2
    Duplicate: [How to trigger a file download when clicking an HTML button or JavaScript](https://stackoverflow.com/questions/11620698/how-to-trigger-a-file-download-when-clicking-an-html-button-or-javascript) –  May 22 '21 at 08:22

1 Answers1

0

I solved it by changing the downloadAnImage function:

 function downloadAnImage(imageLink){
  let link=document.createElement('a');
  link.href = process.env.REACT_APP_PROXY+"/download/"+imageLink
  link.target = "_blank"
  link.download = imageLink;
  link.click();
 }