Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Corrupted download in AngularJs app

I am trying to download a file using FileSaver.js, but I get a corrupted file whenever I hit download button.

App is backed by a PHP REST service, and using cURL from command line confirms that REST is working OK.

Here is last version of pseudo-code that I use for downloading:

// Let str be the data received from $http promise
// This code is run in a "then" callback

var arr= new Uint8Array(str.length);
for(var i=0; i<str.length; i++) {
    arr[b]=str.charCodeAt(i);
};
var blob = new Blob([arr], {type: 'application/octet-stream'});
saveAs(blob, "AFileName");

It just corrupts file.

I also tried without applying the Uint8Array, and giving str directly to Blob. As you guessed, it failed too.

I am writing server and client myself, so I can change anything in them. But the thing is I want to handle downloads client-side, and I just can't redirect users to file URL to download it, because REST needs authentication and that token only lives within Angular app. It would not be a good choice to change server just to handle file downloads without authentication.

The REST has URLs like /files/:id that when accessed, gives file content as a regular HTTP file download (tested with cURL as said above). Could $http be the problem? Somehow forcing some kind of encoding or some assumptions on received data. I don't have much experience in Angular, anyway.

like image 532
vfsoraki Avatar asked Oct 10 '15 07:10

vfsoraki


1 Answers

I have found the problem. It was me :)

I had to specify responseType: "arraybuffer" for $http then give str directly to Blob.

Fixed code

// Let str be the data received from $http promise
// This code is run in a "then" callback
// Make sure to specify "responseType: "arraybuffer"" for $http

var blob = new Blob([str], {type: 'application/octet-stream'});
saveAs(blob, "AFileName");

I was changing responseType in wrong place.

like image 200
vfsoraki Avatar answered Nov 14 '22 18:11

vfsoraki