简体   繁体   English

如果以文件名的附件形式接收到AngularJS $ resource响应,如何触发Spinner进行文件下载或如何在浏览器中下载文件

[英]How to trigger Spinner for file download or How to download file in browser if AngularJS $resource response received as an attachement with file name

I'm able to download successfully using below line of code in AngularJS controller. 我可以在AngularJS控制器中使用以下代码行成功下载。

$window.location.href =$rootScope.urlBase+'/dios/download/lineitemexcel/'+$routeParams.id

But, when data is large and it is taking longer time, for this reason I need to enable angular-Spinner. 但是,当数据很大且需要较长时间时,由于这个原因,我需要启用angular-Spinner。 No way I could find a way to start spinner before the call and it should finish after file download finished in the browser. 我无法找到在调用之前启动Spinner的方法,并且应该在浏览器中文件下载完成后才能完成。

Root Problem: How can I enable spinner with existing plugin in the project angular-spinner or usSpinnerService? 根本问题:如何在项目angular-spinner或usSpinnerService中使用现有插件启用旋转器? if this has a solution I dont have next question. 如果这有解决方案,我没有下一个问题。

To Solve this problem, I have gone through existing spinner working flow. 为了解决这个问题,我已经完成了现有的微调器工作流程。 Spinner is working if there is $resource call. 如果有$resource调用,则微调器正在工作。

Hence above url I tried by forming factory call like below: 因此,在上面的网址中,我尝试通过形成如下的工厂调用来尝试:

Service: 服务:

factory('Dios', ['$resource','$rootScope',
        function($resource, $rootScope){
            return $resource($rootScope.urlBase+'/dios/:id/:status/:third/:fourth/:fifth/:pageNo', {}, {
                get: {
                    method: 'GET'
                },
                update: {
                    method: 'PUT'
                },
                getexcel: {
                    method: 'GET',
                    transformResponse: function(data, headers,status){
                        var dataTransformed = {};
                        dataTransformed.data=data;
                        dataTransformed.headers=headers;
                        dataTransformed.status=status;
                        return dataTransformed;
                    }
                }
            });
        }])

Controller: 控制器:

Dios.getexcel({dios:'dios',third:'download',fourth:'lineitemexcel',fifth: $routeParams.id},function(data){
                console.log(data);
]);

Using above factory call rest call with an Id of an Object. 将上述工厂调用rest调用与对象的id一起使用。 That Object I need to retrieve and process using Apache POI JAVA library , and Apache POI library will return as an attachement with response header properties in dev tools network tab as follows: 我需要使用Apache POI JAVA库进行检索和处理的对象,并且Apache POI库将作为附件返回,并带有在dev tools网络选项卡中的响应标头属性,如下所示:

HTTP/1.1 200 HTTP / 1.1 200

X-Content-Type-Options: nosniff X-Content-Type-Options:nosniff

X-XSS-Protection: 1; X-XSS-Protection:1; mode=block 模式=块

Cache-Control: no-cache, no-store, max-age=0, must-revalidate 缓存控制:无缓存,无存储,最大年龄= 0,必须重新验证

Pragma: no-cache 语法:无缓存

Expires: 0 过期:0

X-Frame-Options: DENY X-Frame-Options:DENY

Access-Control-Allow-Origin: http://10.218.39.45:9000 Access-Control-Allow-Origin: http : //10.218.39.45 : 9000

Access-Control-Allow-Credentials: true 访问控制允许凭据:true

Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS, DELETE 访问控制允许方法:POST,GET,PUT,OPTIONS,DELETE

Access-Control-Allow-Headers: Content-Type,X-Requested With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers 访问控制允许标题:内容类型,X请求,接受,来源,访问控制请求方法,访问控制请求标题

Access-Control-Expose-Headers: 1,Access-Control-Allow-Origin,Access-Control-Allow-Credentials Access-Control-Expose-Header:1,Access-Control-Allow-Origin,Access-Control-Allow-Credentials

Content-Disposition: attachment; 内容处置:附件; filename=LineItems-of_IO-1553-8531Testing_2018-09-18.xlsx 文件名=了LineItem-of_IO-1553-8531Testing_2018-09-18.xlsx

Content-Type: application/vnd.ms-excel 内容类型:application / vnd.ms-excel

Transfer-Encoding: chunked 传输编码:分块

Date: Tue, 18 Sep 2018 08:33:46 GMT 日期:2018年9月18日星期二08:33:46 GMT

In this way I'm able to get spinner but , I am not sure how to download response received as file with specified name in response headers. 这样,我就可以得到Spinner,但是,我不确定如何下载在响应标头中以指定名称作为文件接收的响应。

using transformResponse: I am expecting responseheaders info, but it is not getting attached to headers in transformResponse: . 使用transformResponse:我期待有responseheaders信息,但它没有附加到transformResponse:头上。

So Kindly help me to get spinner is getting triggered for window.location.href=url or help me how download the received data through $resource . 因此,请帮助我让window.location.href=url触发微调器,或帮助我如何通过$resource下载接收到的数据。

I don't see any way to show spinner while downloading file directly using window.location . 使用window.location直接下载文件时,我看不到任何方式显示微调window.location

But downloading file from response can be possible. 但是可以从响应中下载文件。 Can you please try below approach? 您可以尝试以下方法吗?

Delete trasnformResponse from $resource 从$ resource删除trasnformResponse

Write a function to download file 编写函数下载文件

var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";

$scope.downloadFile= function(data, fileName, contentType) {
    var blob = new Blob([data], {
      type: contentType
    });
    var url = URL.createObjectURL(blob);
    a.href = url;
    a.download = fileName;
    a.click();
//hide spinner here
    window.URL.revokeObjectURL(url);
}

Change you function call as 将您的函数调用更改为

Dios.getexcel({dios:'dios',third:'download',fourth:'lineitemexcel',fifth: $routeParams.id},function(data, responseHeader){
    $scope.downloadFile(data, responseHeader()['Content-Disposition'].split('filename=')[1] , responseHeader()['Content-Type']);
]);

First this question has nothing to do with angularjs itself, this is pure js problem. 首先,这个问题与angularjs本身无关,这是纯粹的js问题。 For download there are 2 options: 下载有两个选项:

  1. Download file using Ajax and then store it on disk using createObjectURL. 使用Ajax下载文件,然后使用createObjectURL将其存储在磁盘上。
  2. Download file usual way ie simple href. 通常下载文件的方式,即简单的href。

These two are really different: -1st wont work in some browsers -1st gives you full access over request, you can comfortably handle errors etc. -2nd start download in parallel, eg in chrome you can close tab with app, but download will still proceed 两者实际上是不同的:-1st在某些浏览器中无法使用-1st使您可以完全根据请求进行访问,可以轻松地处理错误等。-2nd并行开始下载,例如在chrome中,您可以使用app关闭选项卡,但下载仍继续

In 1st way showing spinner is relatively easy, you do it as for any other request. 在第一种显示Spinner的方式中,相对简单,您可以像处理其他任何请求一样进行操作。

In 2nd way you usually do not want to show spinner when download is in progress as browser will show progress for you. 在第二种方式中,下载过程中您通常不希望显示微调框,因为浏览器会为您显示进度。 However, before download starts - before response came from server you sometimes may want to show some waiting and the only way this can be done is using cookies: 但是,在开始下载之前-在服务器做出响应之前,您有时可能希望显示一些等待,并且唯一可以使用Cookie的方法是:

  • you add some param to download request eg my-cookie-id=cookie_123 您添加一些参数来下载请求,例如my-cookie-id = cookie_123
  • server sets cookie cookie_123 in response 服务器设置cookie cookie_123作为响应
  • after link is clicked you check for this cookie value (eg each 100ms) 单击链接后,您检查此cookie值(例如,每100ms)
  • when you see this cookie value, your file is started to download 当您看到此Cookie值时,便开始下载文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM