我试图通过angular.js实现文件下载
该文件来自服务器的二进制格式,内容类型为application/octet-stream
下载是使用$resource
的GET。查看传递给回调的参数(下面称为content
),它是一个包含字节数组的对象,还包含$resource
的属性列表。
尝试了多种方式来提供文件,但没有成功。
首先是:
...
var a = document.createElement('a');
a.href = "data:attachment/zip," + content;
a.download = zipName;
a.click();
在这种情况下,zip文件的内容为[object Object]
我尝试从对象中提取数组并将所有内容连接到字符串变量中。在这种情况下,zip文件大于正常大小。我必须在调用isArray: true
的服务中设置$resource
,否则无法从响应对象中提取字节内容。
我是这样做的:
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();
值得一提的是,在encodeURI
上调用str
会大幅增加下载的zip的大小,但存档仍然无效。
我还尝试从Blob
创建str
并将内容类型设置为application/octet-stream
,但没有任何运气。
var blob = new Blob([str], {'type':"application/octet-stream"});
a.href = window.URL.createObjectURL(blob);
...
不知道我在这里丢失了什么,但在模拟点击下载之前,它看起来很难获得字节数组内容的正确格式并设置正确的href
。
非常感谢帮助。
由于
答案 0 :(得分:1)
我刚找到你的帖子,并根据你的名单修正了答案。
首先,您必须确保您的angular $ http请求包含,如下面的获取示例(include responseType: 'arraybuffer'
)
$http.get('/downloadZip', {
params: {
file: encodeURIComponent(filepath)
},
responseType: 'arraybuffer'
//your code
在您的成功或承诺处理程序中,您应该将window.URL.createObjectURL(blob)
更改为URL.createObjectURL(blob)
。实现类似于以下内容:
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();
通过这些,您将创建一个新的锚元素并模拟打开它。正确修改了Blob,因为请求已被正确修改。
答案 1 :(得分:1)
不需要Angular。
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);
答案 2 :(得分:0)
如果有人仍在使用AngularJS(例如我)并且想要这样做,我接受了David的回答,并使其与angular $ resource一起使用,而不是直接使用较低级别的$ http。如果您使用$ resource,这应该对您有帮助:
var myReportingResource = $resource(baseURL + '/mypath/:command', {},{
getExportZip: {
method: 'GET',
params: {
command: 'exportzip'
},
responseType: 'arraybuffer',
// don't try to convert the zip to JSON
// instead take the data that comes 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();
});
您需要transformResponse
位,因为否则AngularJS会将您的响应转换为JSON,这对于二进制数据是错误的。这就是为什么以后使用zipData.content
将数据传递到Blob的原因。您可以摆脱content
部分,这里有简单的错误处理代码。
自2019年5月起,此功能可在Chrome和Safari中使用。未在其他任何地方进行测试。