Javascript 客户端下载服务器生成的 zip 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37948809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Client download of a server generated zip file
提问by westandy
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
1)使用angular和php,不确定这里发生了什么(我不知道PHP):下载zip文件并从angular方法触发“保存文件”对话框
2) Can't get this answer to do anything: how to download a zip file using angular
2) 无法得到这个答案做任何事情:如何使用 angular 下载 zip 文件
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
3)这个人已经可以下载了,这已经超出了我想弄清楚的点: 从按钮动作触发的角度下载外部zip文件
4) No answer for this one: download .zip file from server in nodejs
4) 没有答案: 从 nodejs 中的服务器下载 .zip 文件
5) I don't know what language this even is: https://stackoverflow.com/questions/35596764/zip-file-download-using-angularjs-directive
5)我什至不知道这是什么语言: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.
我的 angular 1.5.X 客户端给了我一个标题列表,每个标题都有一个关联的文件。我的 Node 4.X/Express 4.X 服务器获取该列表,获取文件位置,创建一个 zip 文件,使用来自 npm 的 express-zip,然后将该文件流式传输回响应。然后我希望我的客户端启动浏览器的“下载文件”选项。
Here's my client code (Angular 1.5.X):
这是我的客户端代码(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:
带有express-zip 的Node (4.X) 代码,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):
这是我的客户端代码(Angular 1.5.X)中的 successCb:
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?
“blob”部分似乎工作正常。在 IE 的调试器中检查它,它看起来确实像一个八位字节信息的文件流。现在,我相信我需要将该 blob 放入一些 HTML5 指令中,以从浏览器启动“文件另存为”。也许?也许不吧?
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:
由于我们 90% 以上的用户都在使用 IE11,我在 PhantomJS (Karma) 和 IE 中测试了我的所有 angular。当我运行代码时,我在警报窗口中收到旧的“访问被拒绝”错误:
Exception: {"description":"Access is denied...<stack trace>}
Suggestions, clarifications, answers, etc. are welcome!
欢迎提出建议、澄清、回答等!
采纳答案by westandy
I updated my bulkdownload
method to use $window.open(...)
instead of $http.get(...)
:
我更新了我的bulkdownload
方法来使用$window.open(...)
而不是$http.get(...)
:
function bulkdownload(titles){
titles = titles || [];
if ( titles.length > 0 ) {
var url = '/query/bulkdownload?';
var len = titles.length;
for ( var ii = 0; ii < len; ii++ ) {
url = url + 'titles=' + titles[ii];
if ( ii < len-1 ) {
url = url + '&';
}
}
$window.open(url);
}
};
I have only tested this in IE11.
我只在 IE11 中测试过这个。
回答by Chinmay235
Use this one:
使用这个:
var url="YOUR ZIP URL HERE";
window.open(url, '_blank');
回答by atom
var zip_file_path = "" //put inside "" your 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);
回答by Bahadir Tasdemir
As indicated in this answer, I have used the below Javascript function and now I am able to download the byte[] array
content successfully.
如本答案所示,我使用了以下 Javascript 函数,现在可以byte[] array
成功下载内容。
Function to convert byte array stream (type of string) to blob object:
将字节数组流(字符串类型)转换为 blob 对象的函数:
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
):
这就是我调用此函数并使用FileSaver.js保存 blob 对象的方式(通过 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[] array
(Java-Server-Side):
byte[] myByteArray = /*generate your zip file and convert into byte array*/ new byte[]();
return new ResponseEntity<byte[]>(myByteArray , headers, HttpStatus.OK);