誰かが「重複する」と言う前に、私は人々が知っていることを確認したいだけです。
1)angularとphpを使用します。ここで何が起こっているのかわかりません(PHPはわかりません): Zipファイルをダウンロードし、angularメソッド
2)この答えで何もできない: angularを使用してZipファイルをダウンロードする方法
3)この人はすでにダウンロードできますが、これは私が理解しようとしているポイントを超えています: 外部のZipファイルをダウンロードangularボタンアクションでトリガー
4)これに対する答えはありません: nodejsのサーバーから.Zipファイルをダウンロード
5)これが何の言語かわからない: https://stackoverflow.com/questions/35596764/Zip-file-download-using-angularjs-directive
それらの質問を考慮して、これがまだ重複している場合は、お詫び申し上げます。ここに、まだ、この質問の別のバージョンがあります。
My angular 1.5.Xクライアントは、タイトルのリストを提供し、それぞれに関連ファイルがあります。MyNode 4.X/Express 4.Xサーバーそのリストを取得し、ファイルの場所を取得し、npmからのexpress-Zipを使用してZipファイルを作成し、そのファイルを応答でストリーミングします。次に、クライアントにブラウザーの「ファイルのダウンロード」オプションを開始してもらいます。
これが私のクライアントコードです(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));
};
};
express-Zip、 https://www.npmjs.com/package/express-Zip を含むノード(4.X)コード:
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)
}
});
これが私のクライアントコード(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);
}
};
「ブロブ」の部分は問題なく動作するようです。 IEのデバッガーで確認すると、オクテット情報のファイルストリームのように見えます。今、私はそのblobをいくつかのHTML5ディレクティブに入れて、ブラウザーから「名前を付けて保存」を開始する必要があると思います。多分?そうでないかもしれない?
ユーザーの90%以上がIE11を使用しているため、PhantomJS(Karma)とIEですべてのangularをテストします。コードを実行すると、古い「アクセスが拒否されました」エラーが表示されます警告ウィンドウで:
Exception: {"description":"Access is denied...<stack trace>}
提案、説明、回答などは大歓迎です!
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);
}
};
IE11でのみテストしました。
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);
これを使用してください:
var url="YOUR Zip URL HERE";
window.open(url, '_blank');
この回答 に示されているように、以下のJavascript関数を使用して、byte[] array
コンテンツを正常にダウンロードできるようになりました。
バイト配列ストリーム(文字列のタイプ)を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;
};
これは私がこの関数を呼び出して 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);
});
注:私は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);