如何在AngularJS客户端中将字节数组下载为zip文件?

时间:2019-02-20 07:01:03

标签: angularjs blob angular-http arraybuffer filesaver.js

我确信多年来,这里已经多次问过这个问题和类似的变体了。我经历了几乎所有事情,仍然无法正确执行此操作。

我有一个.NET Core API端点,该端点返回一个表示zip文件的字节数组:

    [HttpGet]
    [Route("download/{fileId}/")]
    public byte[] Download(long fileId)
    {
        ...
    }

我将AngularJS的$http服务与arraybuffer用作responseType来发起请求:

    // AngularJS service (fileApiService)

    this.downloadFile = function (fileId) {
        var url = apiUrl + 'download/' + fileId;
        return $http.get(url, { responseType: 'arraybuffer' });
    };

我得到一个有效的答复,其处理方式如下。我使用FileSaver.js访问saveAs方法和Blob构造函数:

    // AngularJS controller

    fileApiService.downloadFile(fileId)
        .then(function (response) {
           var data = response.data;
           var blob = new Blob([data], { type: 'application/octet-stream' });

           FileSaver.saveAs(blob, 'file.zip');   
        })
        .catch(function () {
            ...
        });

response

不幸的是,无论我对上面的代码进行任何调整,这都会导致存档文件损坏。 Window 10 zip实用程序抱怨即使文件不为空,也无法打开存档。我尝试了以下方法:

  • responseType请求中将blob设置为$http.get(),并将其直接传递到FileSaver.saveAs()方法中
  • application/zip和其他MIME类型传递给Blob构造函数
  • { autoBOM: true }传递给FileSaver.saveAs()方法

我怀疑这是一个编码问题,因为另一个ASP.NET Web窗体应用程序可以从同一API端点下载有效的zip文件。

任何指针将不胜感激。预先感谢!

1 个答案:

答案 0 :(得分:1)

尝试一下

public class Oauth2TokenStore extends RedisTokenStore {
    @Autowired
    private ClientDetailsService clientDetailsService;


    public Oauth2TokenStore(RedisConnectionFactory connectionFactory) {
        super(connectionFactory);
    }

    @Override
    public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
        Object principal = authentication.getPrincipal();

        //Principal is consumer key since we only support client credential flow
        String consumerKey = (String) principal;

        //get client detials
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId(consumerKey);


        // Logic to Create JWT
        .
        .
        .
        //Set it to Authentication
        authentication.setDetails(authToken);

       super.storeAccessToken(token, authentication);
    }

    @Override
    public OAuth2Authentication readAuthentication(String token) {
        OAuth2Authentication oAuth2Authentication =  super.readAuthentication(token);
        if (oAuth2Authentication == null) {
            throw new InvalidTokenException("Access token expired");
        }
        return oAuth2Authentication;
    }
}
}

希望这会有所帮助。