Search code examples
javascriptnode.jsexpresspiperesponse

Failed to download an image file from my node js server through my frontend (my backend and frontend are decoupled)


My nodejs backend is running on localhost:8080 and frontend on localhost:8081 using http-server, I am not able to download file from my server side to client side, I am new to node js so facing some problems with it

What I tried

I created a readstream to my required file on server side and then pipe it to res object , also I set some headers :-

res.setHeader("Content-Type","image/png") // as I am trying to download a 
res.setHeader("Content-Disposition", `inline; filename=${filename}`);

But it still fails

Code:-

code for downloading a file from server side

let filename = "hello.png";
let readStream = fs.createReadStream(path.join(__dirname, "..", chatDoc.chatContent));
res.setHeader("Content-Type", "image/png")
res.setHeader("Content-Disposition", `inline; filename=${filename}`);
readStream.pipe(res);

cors code:-

const cors = require("cors");
app.use(cors({
    origin: "http://localhost:8081",
    credentials: true,
    withCredentials: true
}))

frontend code:-

fetch("http://localhost:8080/downloadNow",{
    method:"POST",
    headers:{
      "Content-Type":"application/json"
    },
    body:JSON.stringify({
      chatId:chatId
    }),
    credentials:"include"
  })
  .then((data) => {
    console.log(data);
  })
  .catch((err) => {
    console.log(err);
  })

Response on frontend:- I got successfully response from server but file isn't downloaded.

enter image description here

please help me out with this


Solution

  • Is that all of your servercode handling the download? If yes, you are not waiting for the readStream to properly open. And you should also add proper error handling, when the readStream couldn't be opened. Use

    let readStream = fs.createReadStream(path.join(__dirname, "..", chatDoc.chatContent));
    readStream.on("open", () => {
      res.setHeader("Content-Type","image/png")
      res.setHeader("Content-Disposition", `inline; filename=${filename}`);
      readStream.pipe(res);
    })
    readStream.on("error", e => {
      console.log(e);
      res.writeHead(400);
    });
    

    And to download a file with fetch(in my understanding this means saving the file to disk instead of displaying it in the browser) you nonetheless need to apply the means of the referenced question ...