2016-06-21 213 views
4

之前有人說,「複製」,我只是想確保,即人們知道,我已經審查了這些問題:客戶端下載

1)使用的角度和PHP,不肯定這裏發生了什麼(我不知道PHP):Download zip file and trigger "save file" dialog from angular method

2)不能得到這個答案,做任何事情:how to download a zip file using angular

3)此人已經可以下載,這是過去的時候,我正試圖弄清楚: Download external zip file from angular triggered on a button action

4)沒有回答這一個: download .zip file from server in nodejs

5)我不知道用什麼語言這甚至是: https://stackoverflow.com/questions/35596764/zip-file-download-using-angularjs-directive

鑑於這些問題,如果這仍然是一個重複的,我道歉。這是另一個版本的問題。

我的角度1.5.X客戶端給我一個標題列表,其中每個標題都有一個關聯的文件。我的節點4.X/Express 4.X服務器獲取該列表,獲取文件位置,使用npm中的express-zip創建一個zip文件,然後將該文件傳回給響應。然後我希望我的客戶端啓動瀏覽器的「下載文件」選項。

這裏是我的客戶端代碼(角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)); 
    }; 
}; 

節點(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) 
    } 
}); 

這裏是我的successCb在我客戶端代碼(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); 
    } 
}; 

「blob」部分s eems工作正常。在IE的調試器中檢查它,它看起來像一個八位字節信息的文件流。現在,我相信我需要將該blob放入一些HTML5指令中,從瀏覽器啓動「另存文件」。也許?也許不會?

由於90%以上的用戶使用IE11,我測試了PhantomJS(Karma)和IE中的所有角度。當我運行的代碼,我得到的是舊「訪問被拒絕」的一個警告窗口錯誤:

Exception: {"description":"Access is denied...<stack trace>} 

建議,澄清,解答等,歡迎!

+1

所以會發生什麼?它在哪一點失敗?你偶然有一個彈出式窗口攔截器嗎? – idbehold

+0

是否有錯誤?如果手動輸入url http:// localhost/query/bulkdownload?titles = 123',你可以下載文件嗎? –

+0

哦拍!對不起,讓我更新一下。 – westandy

回答

0

我更新了我的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測試這一點。

2
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); 
0

this answer指出,我用下面的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; 
}; 

一種這是我的調用此函數和(經由Angular.js $http.get獲取數據)FileSaver.js保存blob對象:

$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的服務器端)是這樣的:

byte[] myByteArray = /*generate your zip file and convert into byte array*/ new byte[](); 
return new ResponseEntity<byte[]>(myByteArray , headers, HttpStatus.OK); 
1

使用這一個:

var url="YOUR ZIP URL HERE"; 
window.open(url, '_blank');