【问题标题】:How to download a zip file in AngularJS / FilesaverJS [duplicate]如何在 AngularJS / FilesaverJS 中下载 zip 文件 [重复]
【发布时间】:2017-05-23 22:08:48
【问题描述】:

我有一个服务函数,它返回 3 个结果文件(2 个文本文件,1 个 zip 文件)。

我想检查响应的标题以查看文件是 zip 还是文本以设置正确的配置以下载文件。

我的控制器解决了我的服务的承诺。如果我下载一个文本文件 -> 文件显示 [object object] ..

我在浏览器中看到响应正文来自 content-type: text/plain

我有点困惑:/

控制器:

$scope.getResult = function(rid) {
        console.log($scope.id);
        GetResultFile.getResult($scope.id, rid)
        .then(function (data, headers) {
            //console.log(headers(Content-type));
            console.log("Download erfolgreich");
            console.log(data.status);
            var file = new Blob([data], {type: 'text/plain;charset=utf-8'});
            FileSaver.saveAs(file, 'test.txt');

        }, function (data) {
            console.log("Download ERROR!");
            console.log(data.status);
        })
    };      

服务:

.factory('GetResultFile',
['$http', '$q',
function ($http, $q) {

    var service = {};
    service.getResult = function(id, rid) {

        var deferred = $q.defer();

        $http
        .get('http://localhost:9999/v1/jmeter/' + id + '/results/' + rid, {cache: false})
        .then(function(data, status, headers, config) {
            if(data.status == 200) {
                console.log(data.status);
                deferred.resolve(data);
            }
            else {
                deferred.reject(data);
            }
        });
        return deferred.promise;                
    }
    return service;

查看:

<span ng-show="dataTable">
    <table>
        <tr ng-repeat="r in results">
            <td><a href="" ng-click="getResult(r.id)" download>{{r.name}}</a></td>
        </tr>
    </table>
</span>

更新:

这是我的服务,我将 responsetype 设置为 arraybuffer

.factory('GetZip',
['$http', '$q',
function ($http, $q) {

    var service = {};
    service.getZip = function(id, rId) {

        var deferred = $q.defer();

        $http
        .get('http://localhost:9999/v1/jmeter/' + id + '/results/' + rId, {cache: false, responseType: 'arraybuffer'})
        .then(function(response) {
            if(response.status == 200) {
                console.log(response.status);
                deferred.resolve(response);
            }
            else {
                deferred.reject(response);
            }
        });
        return deferred.promise;                
    }
    return service;

这是我在控制器中的调用:

$scope.getResult = function(rId, rName) {
        console.log($scope.id);
        console.log(rName);
        GetResultFile.getResult($scope.id, rId)
        .then(function(response) {
            var data = "";
            var headerType = "";
            data = response.data;
            headerType = response.headers('content-type');
            console.log(response.headers('content-type'));
            console.log("Download erfolgreich");
            console.log(response);
            // zip data need to be handle with a binary stream
            if(headerType == 'application/zip;charset=UTF-8') {
                GetZip.getZip($scope.id, rId)
                .then(function(response) {
                    var file = new Blob([response.data], {type: "application/octet-stream"});
                    FileSaver.saveAs(file, rName);
                    console.log("zipper");
                }, function(response) {
                    console.log("Download ERROR");
                    console.log(response.status);
                })
            } else {
                var file = new Blob([data], {type: headerType});
                FileSaver.saveAs(file, rName);
                console.log("else");
            }
        }, function(response) {
            console.log("Download ERROR!");
            console.log(response.status);
        })
    };              

}])

但如果我下载 zip 文件,它仍然损坏并且在提取 zip 时出错 -.-

【问题讨论】:

  • 那么目前的实际问题是什么?标题提到了 zip 文件,但您询问的是问题中的文本文件。你能扩展..the file says [object object]吗?
  • ups 对不起,文本文件和 zip 文件,我会编辑它

标签: javascript angularjs download angularjs-http


【解决方案1】:

为此,您应该在后端有 2 个单独的休息服务,因此您应该从一个休息端点检索可用文件列表,而不是同时提供所有文件并将它们保存在浏览器中,然后在用户单击时从其中检索特定文件另一个休息端点。您的文件服务可能如下所示:

function downloadFile(src) {
  let header, startIndex, filename;
  $http({
    method: 'GET',
    url: src,
    headers: {
      'Accept': 'text/html,application/xhtml+xml,application/xml,application/pdf;q=0.9,image/webp,*/*;q=0.8',
      'Upgrade-Insecure-Requests': 1
    },
    responseType: 'blob'
  }).then(function (successResponse) {
    header = unescape(successResponse.headers()['content-disposition']);
    startIndex = header.indexOf('filename=');
    filename = header.slice(startIndex + 10,-1);
    try{
      saveAs(successResponse.data, filename);
    }
    catch(error){
      // FileSaver error
    }
  }, function (errorResponse) {
    // Server error has occurred during file downloading.
}

您需要将响应类型指定为 blob。此示例中的变量 src 将是特定端点服务所需的文件(这里它是根据从可用文件列表中检索到的数据从控制器提供的,但如果你想要基于文件的 id 或其他东西,你可以在此处构建它)。在这种情况下,后端在公开的标头中提供完整的文件名,因此您可以提取它并使用正确的名称和格式保存文件。此示例中的提取用于特定的休息响应,但您应该能够对其进行更改以满足您的需求。

示例:内容处置标头将是字符串,类似于:

Content-Disposition: attachment; filename="picture.png"

在这种情况下,服务将提取该名称,而 Filesaver 将保存文件“picture.png”。

【讨论】:

  • 你能检查我对问题的更新吗?还是不行..
  • @Kai 在你的控制器中,var file=.... 什么是数据?你没有对响应做任何事情,它应该类似于 response.data 还确保 rName 是文件的正确名称,我目前不确定你从哪里得到它。
  • data = response.data and rName 是视图中文件的名称,名称正确,数据看起来不错,但是如果我解压缩数据,就会出现错误-.-
  • 好的,我已经解决了!谢谢你的帮助
【解决方案2】:

如何在 AngularJS 中下载 zip 文件

要下载二进制文件类型(例如 zip 文件),请务必在执行 XHR 之前设置 responseType

var config = { responseType: "blob" };

var promise = $http.get(url, config);

promise
  .then(function onSuccess(response) {
    // Handle success
    var data = response.data;
    var status = response.status;
    var statusText = response.statusText;
    var headers = response.headers;
    var config = response.config;
    ...
  }).catch(function onError(response) {
    // Handle error
    var data = response.data;
    var status = response.status;
    var statusText = response.statusText;
    var headers = response.headers;
    var config = response.config;
    ...
  });

有关详细信息,请参阅MDN Web API Reference - XHR responseType

【讨论】:

  • 你能检查我对问题的更新吗,仍然是一个错误
猜你喜欢
  • 2017-07-10
  • 2015-01-02
  • 2021-11-19
  • 1970-01-01
  • 2012-03-08
  • 2018-10-24
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
相关资源
最近更新 更多