简体   繁体   中英

how to send a zip file back end to front end in nodejs using express server

I am building an application where it is required to save data into separate and compress these files into a zip file. these files are at the back end and i could not send this back end created zip file to front end which is react in this case

express js code

app.post("/download",function(request,response,next){
    let sheets=request.body["sheets"];
    let charts=request.body["charts"];
    let compressedSheets=LZString.compress(JSON.stringify(sheets));

    fs.writeFile(__dirname+'/public/dataModel.txt', compressedSheets, function (err) {
        if (err) throw err;
        console.log('Replaced!');

      },()=>{
        fs.writeFile(__dirname+'/public/Report.json',charts,function(err){
            if(err){
                console.log(err);
            }
        },()=>{
            var archiver = require('archiver');
            var output = fs.createWriteStream(__dirname+'/public/example.zip');
            var archive = archiver('zip', {
                gzip: true,
                zlib: { level: 9 } // Sets the compression level.
            });

            archive.on('error', function(err) {
            throw err;
            });
            archive.pipe(output);
            archive.file(__dirname+'/public/dataModel.txt', {name: 'dataModel.txt'});
            archive.file(__dirname+'/public/Report.json', {name: 'Report.json'});


            archive.finalize().then(()=>{
                response.setHeader('Content-disposition', 'attachment; filename=example.zip');
                response.download(__dirname+'/public/example.zip');
            });

        })
      });

react code

handleSaveAs=function(){


    let data=new FormData();
    data.append('sheets',JSON.stringify(this.state.sheets));
    data.append('charts',JSON.stringify(this.state.charts));


    axios
    .post("http://localhost:4001/download",data)
    .then(res=>{
      console.log(res);
      const element = document.createElement("a");
      const file = new Blob([res.data], {type: 'application/zip'});
      element.href = URL.createObjectURL(file);
      element.download = "untitled.zip";
      document.body.appendChild(element);
      element.click();
    })

provided all the imports are handled properly and the zip file is created properly at the back end. problem is only with sending that to front end

any help would be appreciated thank you

You can use the in-built fs of Node.js to stream the data to the front-end.

//Filestream middleware that takes in the file path as the parameter

const streamW = (pathToZip) => {
 return (req, res, next) => {

//Create a readable stream
const readableStream = fs.createReadStream(pathToZip, 'the_encoding_here');

//Pipe it into the HTTP response
readableStream.pipe(res)

  next();

}};

//The route that you want to hit using the front-end to get the file
//Call the middleware and pass in the path to the zip
router.get('/downloadRoute', streamW('path_to_zip'), (req, res) => {

     //Send the data to the front end by calling res
     res

// });

This you do in node.js download route

     archive.finalize().then(()=>{
  let filetext = fs.readFileSync(__dirname+'/public/example.zip');

  return res.end(new Buffer(filetext ).toString('base64'));
});

On frontend do something like this

handleSaveAs=function(){

let data=new FormData();
data.append('sheets',JSON.stringify(this.state.sheets));
data.append('charts',JSON.stringify(this.state.charts));


axios
.post("http://localhost:4001/download",data)
.then(res=>{
  console.log(res);
  let elem = window.document.createElement('a');
    elem.href = "data:application/zip;base64,"+res;
    elem.download = "my.zip";        
    document.body.appendChild(elem);
    elem.click();        
    document.body.removeChild(elem);
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM