admin管理员组文章数量:1318580
I'm trying to implement the download of a file through angular.js
The file es from the server in binary format, the content type is application/octet-stream
The download is a GET using $resource
. Looking at the parameter passed to the callback (called content
below), it's an object containing the byte array and also a list of properties for $resource
.
Tried several ways to serve the file, but without success.
First of them:
...
var a = document.createElement('a');
a.href = "data:attachment/zip," + content;
a.download = zipName;
a.click();
In this case, the content of the zip file is [object Object]
I tried extracting the array from the object and joining everything into a string variable. The zip file in this case is way larger than the normal size. I had to set isArray: true
in the service that calls $resource
, otherwise there was no way to extract the byte content from the response object.
Here is how I did it:
var str = '';
for (var i = 0; i < content.length; i++) {
str += content[i][0];
}
...
var a = document.createElement('a');
a.href = "data:attachment/zip," + str;
a.download = zipName;
a.click();
Worth mentioning that calling encodeURI
on str
increments drastically the size of the downloaded zip, but the archive remains invalid.
I also tried creating a Blob
from the str
and setting the content type to application/octet-stream
, without any luck.
var blob = new Blob([str], {'type':"application/octet-stream"});
a.href = window.URL.createObjectURL(blob);
...
Don't know what I'm missing here, but it looks rather a problem of getting the right format for the byte array content and setting the correct href
before simulating the click for downloading.
Help is appreciated.
Thanks
I'm trying to implement the download of a file through angular.js
The file es from the server in binary format, the content type is application/octet-stream
The download is a GET using $resource
. Looking at the parameter passed to the callback (called content
below), it's an object containing the byte array and also a list of properties for $resource
.
Tried several ways to serve the file, but without success.
First of them:
...
var a = document.createElement('a');
a.href = "data:attachment/zip," + content;
a.download = zipName;
a.click();
In this case, the content of the zip file is [object Object]
I tried extracting the array from the object and joining everything into a string variable. The zip file in this case is way larger than the normal size. I had to set isArray: true
in the service that calls $resource
, otherwise there was no way to extract the byte content from the response object.
Here is how I did it:
var str = '';
for (var i = 0; i < content.length; i++) {
str += content[i][0];
}
...
var a = document.createElement('a');
a.href = "data:attachment/zip," + str;
a.download = zipName;
a.click();
Worth mentioning that calling encodeURI
on str
increments drastically the size of the downloaded zip, but the archive remains invalid.
I also tried creating a Blob
from the str
and setting the content type to application/octet-stream
, without any luck.
var blob = new Blob([str], {'type':"application/octet-stream"});
a.href = window.URL.createObjectURL(blob);
...
Don't know what I'm missing here, but it looks rather a problem of getting the right format for the byte array content and setting the correct href
before simulating the click for downloading.
Help is appreciated.
Thanks
Share Improve this question asked Mar 14, 2014 at 17:22 Horia TomaHoria Toma 1,1292 gold badges17 silver badges30 bronze badges 1- remember that you can run into download problems with IE11 stackoverflow./questions/18755750/… – spankmaster79 Commented Aug 10, 2016 at 11:57
3 Answers
Reset to default 2I just found your post and fixed an answer using what you enlist.
First you have to ensure that your angular $http request includes, like the following get example (
include responseType: 'arraybuffer'
)$http.get('/downloadZip', { params: { file: encodeURIComponent(filepath) }, responseType: 'arraybuffer' //your code
Second on your success or promise handler you should change your
window.URL.createObjectURL(blob)
toURL.createObjectURL(blob)
. Implementing something similar to the following:var a = document.createElement('a'); var blob = new Blob([data], {'type':"application/octet-stream"}); a.href = URL.createObjectURL(blob); a.download = "filename.zip"; a.click();
With these you are creating a new anchor element and simulating to opening it. With a correct Blob creation since the request had been modified correctly.
Angular is no needed.
var zip_file_path = "" //put inside "" your server path with file.zip
var zip_file_name = "" //put inside "" file name or something
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = zip_file_path;
a.download = zip_file_name;
a.click();
document.body.removeChild(a);
In case anyone is still on AngularJS (like me) and wants to do this, I took David's answer and made it work with the angular $resource instead of using the lower level $http directly. If you use $resource, this should help you:
var myReportingResource = $resource(baseURL + '/mypath/:mand', {},{
getExportZip: {
method: 'GET',
params: {
mand: 'exportzip'
},
responseType: 'arraybuffer',
// don't try to convert the zip to JSON
// instead take the data that es back and put it in an object under a content key
transformResponse: function(data){
return {content: data};
}
}
});
// call the resource like this
myReportingResource.getExportZip(yourParams).$promise.then(function(zipData){
// create a anchor element, stick the zip data in it, and click it to download
var anchor = angular.element('<a/>');
anchor.attr({
href: URL.createObjectURL(new Blob([zipData.content], {'type':'application/octet-stream'})),
download: 'myfilename.zip'
})[0].click();
});
You need the transformResponse
bit because otherwise AngularJS will convert your response to JSON- which is wrong with binary data. This is why later you use zipData.content
to pass the data into the Blob. You can get rid of the content
part, it's there for simplicity with my error handling code.
This works in Chrome and Safari as of May 2019. Didn't test anywhere else.
本文标签: javascriptDownloading a zip file using angularStack Overflow
版权声明:本文标题:javascript - Downloading a zip file using angular - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742046908a2417840.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论