Before somebody says, "duplicate", I just want to make sure, that folks know, that I have already reviewed these questions:
1) Uses angular and php, not sure what is happening here (I don't know PHP): Download zip file and trigger "save file" dialog from angular method
2) Can't get this answer to do anything: how to download a zip file using angular
3) This person can already download, which is past the point I'm trying to figure out: Download external zip file from angular triggered on a button action
4) No answer for this one: download .zip file from server in nodejs
5) I don't know what language this even is: https://stackoverflow.com/questions/35596764/zip-file-download-using-angularjs-directive
Given those questions, if this is still a duplicate, I apologize. Here is, yet, another version of this question.
My angular 1.5.X client gives me a list of titles, of which each have an associated file. My Node 4.X/Express 4.X server takes that list, gets the file locations, creates a zip file, using express-zip from npm, and then streams that file back in the response. I then want my client to initiate the browser's "download a file" option.
Here's my client code (Angular 1.5.X):
function bulkdownload(titles){
titles = titles || [];
if ( titles.length > 0 ) {
$http.get('/query/bulkdownload',{
params:{titles:titles},
responseType:'arraybuffer'
})
.then(successCb,errorCb)
.catch(exceptionCb);
}
function successCb(response){
// This is the part I believe I cannot get to work, my code snippet is below
};
function errorCb(error){
alert('Error: ' + JSON.stringify(error));
};
function exceptionCb(ex){
alert('Exception: ' + JSON.stringify(ex));
};
};
Node (4.X) code with express-zip, https://www.npmjs.com/package/express-zip:
router.get('/bulkdownload',function(req,resp){
var titles = req.query.titles || [];
if ( titles.length > 0 ){
utils.getFileLocations(titles).
then(function(files){
let filename = 'zipfile.zip';
// .zip sets Content-Type and Content-disposition
resp.zip(files,filename,console.log);
},
_errorCb)
}
});
Here's my successCb in my client code (Angular 1.5.X):
function successCb(response){
var URL = $window.URL || $window.webkitURL || $window.mozURL || $window.msURL;
if ( URL ) {
var blob = new Blob([response.data],{type:'application/zip'});
var url = URL.createObjectURL(blob);
$window.open(url);
}
};
The "blob" part seems to work fine. Checking it in IE's debugger, it does look like a file stream of octet information. Now, I believe I need to get that blob into the some HTML5 directive, to initiate the "Save File As" from the browser. Maybe? Maybe not?
Since 90%+ of our users are using IE11, I test all of my angular in PhantomJS (Karma) and IE. When I run the code, I get the old "Access is denied" error in an alert window:
Exception: {"description":"Access is denied...<stack trace>}
Suggestions, clarifications, answers, etc. are welcome!
To unzip the entire folder, right-click to select Extract All, and then follow the instructions. To unzip a single file or folder, double-click the zipped folder to open it. Then, drag or copy the item from the zipped folder to a new location.
Credentials = new NetworkCredential(_remoteUser, _remotePass); FtpWebResponse response = (FtpWebResponse)request. GetResponse(); Stream responseStream = response. GetResponseStream(); StreamReader reader = new StreamReader(responseStream); StreamWriter writer = new StreamWriter(destination); writer.
client-zip concatenates multiple files (e.g. from multiple HTTP requests) into a single ZIP, in the browser, so you can let your users download all the files in one click. It does not compress the files or unzip existing archives.
As indicated in this answer, I have used the below Javascript function and now I am able to download the byte[] array
content successfully.
Function to convert byte array stream (type of string) to blob object:
var b64toBlob = function(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
};
An this is how I call this function and save the blob object with FileSaver.js (getting data via Angular.js $http.get
):
$http.get("your/api/uri").success(function(data, status, headers, config) {
//Here, data is type of string
var blob = b64toBlob(data, 'application/zip');
var fileName = "download.zip";
saveAs(blob, fileName);
});
Note: I am sending the byte[] array
(Java-Server-Side) like this:
byte[] myByteArray = /*generate your zip file and convert into byte array*/ new byte[]();
return new ResponseEntity<byte[]>(myByteArray , headers, HttpStatus.OK);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With