Reputation: 623
I have a Node JS Rest get service which send the zip folder created on my server in binary encoded format. But unable to download this on client. I am unable to open the zip.
Server controller
botsController.exportBot = (req,res) =>{
let botId = req.params.botId;
zipFolder("...pathtoZip/", "pathToFolder/my.zip", function(err) {
if(err) {
res.statusCode = 500;
return res.send({
success: false,
message: "Something went wrong while fetching the bot data",
err_details: err
});
} else {
let filetext;
let zipFolder= "pathToFolder/my.zip";
if (fs.existsSync(zipFolder)) {
filetext = fs.readFileSync(zipFolder, "utf-8");//tried encoding binary
}
var headers = {
'Content-Type': 'application/octet-stream',//tried application/zip
'Content-Disposition': "attachment; filename=" + botId + '.zip'
};
res.writeHead(200, headers);
return res.end(filetext,"binary");
}
});
And on angular js Service I have fetch the data. And on component I have downloaded it.But download zip is corrupted it gives error unable to open the zip.
Angular 2 Service
exportBot() {
let token = localStorage.token;
let headerObj = {
'Authorization': token,
responseType: ResponseContentType.ArrayBuffer
};
let headers = new Headers(headerObj);
return this.http.get("export/botId", { headers: headers })
.map((res) => new Blob([res['_body']], { type: 'application/zip' }))
.catch(this.errorHandler);
}
And on component end
exportBot() {
this.loader = false;
this.botdataservice.exportBot()
.subscribe(res => {
console.log(`excel data: ${res}`);
window.open(window.URL.createObjectURL(res));
},
err => {
console.log(err);
})
}
Upvotes: 0
Views: 4035
Reputation: 4876
You can convert your file to base64 by using btoa(unescape(encodeURIComponent(binarydata)))
or in case of array buffer try btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
Either can even send base64 file from your node server
filetext = fs.readFileSync(zipFolder);
return res.end(new Buffer(filetext ).toString('base64'));
in that case change your headers
and use following code to download it
var base64Str = "UEsDBAoAAgAAAMWqM0z4bm0cBQAAAAUAAAAJAAAAdmlub2QudHh0dmlub2RQSwECFAAKAAIAAADFqjNM+G5tHAUAAAAFAAAACQAkAAAAAAABACAAAAAAAAAAdmlub2QudHh0CgAgAAAAAAABABgAUCMddj2R0wFA/Bx2PZHTAWCGE3Y9kdMBUEsFBgAAAAABAAEAWwAAACwAAAAAAA==";
var elem = window.document.createElement('a');
elem.href = "data:application/zip;base64,"+base64Str
elem.download = "my.zip";
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
Upvotes: 1
Reputation: 585
In your package.json add the dependency :
"file-saver": "^1.3.3",
And you can use the file saver on your get request as below :
public getBlob(url: string): Observable<Blob> {
this.showLoader();
return this.http.get(url, {responseType: 'blob'})
.catch(this.onCatch)
.do(res => {
this.onSuccess(res);
}, (error: any) => {
this.onError(error);
})
.finally(() => {
this.onEnd();
});
}
and the method to download :
downloadFile(fileid: string) {
return this._http.getBlob(this._http.backendURL.downloadFile.replace(':fileid', fileid))
}
And the you call the Filesaver when subscribing data as this :
downloadFile() {
this._downloadFileService.downloadFile(this.model.fileid)
.subscribe(
data => {
FileSaver.saveAs(data, this.form.getRawValue().title);
}
);
}
I hope this can help.
Upvotes: 2