簡體   English   中英

客戶端下載服務器生成的zip文件

[英]Client download of a server generated zip file

在有人說“復制”之前,我只是想確保,人們知道,我已經審查了這些問題:

1)使用angular和php,不知道這里發生了什么(我不知道PHP): 下載zip文件並從angular方法觸發“保存文件”對話框

2)無法得到任何答案: 如何使用angular下載zip文件

3)這個人已經可以下載,這是我想要弄清楚的一點: 從按鈕動作觸發的角度下載外部zip文件

4)沒有答案: 在nodejs中從服務器下載.zip文件

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

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

我的1.5.X客戶端給我一個標題列表,每個標題都有一個相關的文件。 我的節點4.X / Express 4.X服務器獲取該列表,獲取文件位置,創建一個zip文件,使用來自npm的express-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的節點(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”部分似乎工作正常。 在IE的調試器中檢查它,它看起來像八位字節信息的文件流。 現在,我相信我需要將這個blob放到一些HTML5指令中,以啟動瀏覽器中的“Save File As”。 也許? 也許不吧?

由於90%以上的用戶都在使用IE11,我在PhantomJS(Karma)和IE中測試了所有角度。 當我運行代碼時,我在警報窗口中收到舊的“訪問被拒絕”錯誤:

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

歡迎提出建議,澄清,答案等!

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');

我更新了我的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中測試過這個。

本回答所示 ,我使用了以下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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM