Search code examples
node.jsaxiosnestjsfsadm-zip

Download files from server


All files downloaded are corrupted. I saw in some tutorials saying that this is caused by the passing from backend to frontend, the data will be transformed. But I don't know how to pass the file from backend to frontend. Appreciate any help given. Forgive me if it's a silly question. This is my first question.

https://stackoverflow.com/questions/33789241/file-download-giving-corrupt-file-in-nodejs

Here's my code Server Side:

@Post('downloadDB')
    @Header('Content-Type', 'application/octet-stream')
    @Header('Content-Disposition',`attachment; filename=123`)
    async downloadDB(@Res() res: Response) {
        try {
            const zip = new AdmZip();
 
            zip.addLocalFile("/path/to/file.db");
        
            // Define zip file name
            const downloadName = `${Date.now()}abc.zip`;
        
            const data = zip.toBuffer();
        
            // save file zip in root directory
            zip.writeZip(__dirname+"/"+downloadName);
            
            
            res.setHeader('Content-Disposition', `attachment; filename=${downloadName}`);
            res.setHeader('Content-type', "application/zip");
            var stream = fs.createReadStream(__dirname+"/"+downloadName);
            res.download(__dirname+"/"+downloadName);
            
        } catch (e) {
            console.error(e)
            res.status(500).end();
        }
    }

Client Side:

axios.post(
        '/api/v1/config/downloadDB', 
        { responseType: 'blob' },
        {headers: {
            'Content-Type': 'multipart/form-data',
            'responseType': 'arraybuffer'
        }}
    ).then(function (response) {
        if (response.data.error) {
            console.error(response.data.error)
        }
        const disposition = response.request.getResponseHeader('Content-Disposition');
        var filename = "";
        var filenameRegex = /filename[^;=n]*=((['"]).*?2|[^;n]*)/;
        var matches = filenameRegex.exec(disposition);
        if (matches != null && matches[1]) {
            filename = matches[1].replace(/['"]/g, '');
        }
        let blob = new Blob([response.data], {type: 'application/zip'});
        const downloadUrl = URL.createObjectURL(blob);
        let a = document.createElement('a');
        a.href = downloadUrl;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        a.remove();

Solution

  • Try this one

    Server

    app.post('/imageDownload', async(req, res) => {
     const admzip = require('adm-zip')
     var zip = new admzip();
     var outputFilePath = Date.now() + "output.zip";
     zip.addLocalFile('imagepath')
     fs.writeFileSync(outputFilePath, zip.toBuffer());
     res.download(outputFilePath,(err)=>{
      if(err)
       console.log(err)
     }
    })
    

    Client

    axios({
        url: `/imageDownload`,
        method: 'POST',
        responseType: 'blob',
    }).then((response) => {
          const url = window.URL.createObjectURL(new Blob([response.data]));
          const link = document.createElement('a');
          link.href = url;
          link.setAttribute('download', 'filename.zip'); 
          document.body.appendChild(link);
          link.click();
    });