在angularjs中处理来自代理的HTTP 302响应

D0m*_*0m3 35 http-status-code-302 angularjs

我有一个反向代理,检查几个应用程序的全局身份验证.当用户断开连接但仍尝试使用我的应用程序时,代理会发送302响应:

HTTP/1.1 302 Found
Date: Wed, 11 Sep 2013 09:05:34 GMT
Cache-Control: no-store
Location: https://other.url.com/globalLoginPage.html
Content-Length: 561
Content-Type: text/html; charset=iso-8859-1
Via: 1.1 my-proxy.com
Connection: Keep-Alive
Run Code Online (Sandbox Code Playgroud)

在angularJs中,调用错误回调,但响应头为空,状态为0,数据为空字符串.所以似乎我真的无法处理响应...
我已经看到了关于这个主题的几个问题,我仍然不明白发生了什么(CORS因为代理或不同的域名location?,302浏览器行为?).
特别是这部分来自答案(/sf/answers/1253241321/):

注意:如果您的服务器设置响应代码301或302,您将无法获取Location标头,因为XMLHttpRequest对象将自动且透明地跟随它.

这个XMLHttpRequest对象怎么样?
在一个非常旧版本的Chrome(不能使用更新的版本)中,我可以在网络面板中看到相应的请求,但由于没有响应,它似乎失败了.
在最新版本的Firefox中,没有任何进展.

我可以做任何事情,因为我无法更改代理配置和响应吗?

更新:
我今天重播了我的场景,并且由于更新版本的firebug,我能够获得有关正在发生的事情的更多细节.
在我的问题中,我离anwser不远:跨域策略.
由于它是我的应用程序发出的HTTP请求,因此浏览器拒绝以下XMLHttpRequest(该应用程序看起来像是同一个请求).因此错误和空响应.
所以我认为我无能为力

Ofe*_*gev 43

我的应用程序中遇到了同样的问题.你无法真正"捕获"302重定向响应.浏览器在Angular得到它之前抓住了它.所以实际上,当你收到你的回复时 - 已经太晚了.

坏消息:角度平台不是问题.xmlHttpRequest不支持这种行为,浏览器在您可以执行任何操作之前执行操作.reference:防止重定向Xmlhttprequest

好消息:有很多方法可以绕过这个问题,通过拦截响应 - 并找到一些方法来识别它是你的可爱302.这是一个黑客,但它是你现在可以做的最好的.

所以. 例如,在我的应用程序中,重定向返回到应用程序的login.html页面,在应用程序中,我获得了200状态的响应,响应数据是我的login.html页面的内容.所以在我的拦截器中,我检查结果是否是一个字符串(通常不是!所以 - 没有效率问题..)如果是这样 - 检查它是否是我的login.html页面.这样,我可以抓住重定向并按我的方式处理它.

yourApp.factory('redirectInterceptor', ['$location', '$q', function($location, $q) {
    return function(promise) {
        promise.then(
            function(response) {
                if (typeof response.data === 'string') {
                    if (response.data.indexOf instanceof Function &&
                        response.data.indexOf('<html id="ng-app" ng-app="loginApp">') != -1) {
                        $location.path("/logout");
                        window.location = url + "logout"; // just in case
                    }
                }
                return response;
            },
            function(response) {
                return $q.reject(response);
            }
        );
        return promise;
    };
}]);
Run Code Online (Sandbox Code Playgroud)

然后将此拦截器插入您的应用程序.这样的事情:

$httpProvider.responseInterceptors.push('redirectInterceptor');
Run Code Online (Sandbox Code Playgroud)

祝好运.

  • @OferSegev,您的解决方案只有在重定向到同一域中的url时才是正确的. (2认同)

MBi*_*ski 3

您的 302 -Redirect 是由浏览器直接处理的,您无能为力。但是,您可以使用httpInterceptor来帮助您。您需要将其包含$httpProvider在应用程序 DI 列表中,然后在配置函数中的某个位置放置对它的引用,如下所示:

$httpProvider.responseInterceptors.push('HttpInterceptor');
Run Code Online (Sandbox Code Playgroud)

拦截器示例如下所示:

window.angular.module('HttpInterceptor', [])
.factory('HttpInterceptor', ['$q', '$injector',
    function($q, $injector) {
        'use strict';

        return function(promise) {
            return promise.then(success, error);
        };

        function success(response) {
            return response;
        }

        function error(response) {
            var isAuthRequest = (response.config.url.indexOf('/v1/rest/auth') !== -1);

            //if we are on the authenticating don't open the redirect dialog
            if (isAuthRequest) {
                return $q.reject(response);
            }

            //open dialog and return rejected promise
            openErrorDialog(response);
            return $q.reject(response);
        }

        function openErrorDialog(response) {
            $injector.get('$dialog').dialog({
                backdropFade: true,
                dialogFade: true,
                dialogClass: 'modal newCustomerModal',
                resolve: {
                    errorData: function() {
                        return response.data;
                    },
                    errorStatus: function() {
                        return response.status;
                    }
                }
            })
            .open('/views/error-dialog-partial.htm',
                'errorDialogController')
            .then(function(response) {
                if (response) {
                    window.location = '/';
                }
            });
        }
    }
]);
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的回答,但我不知道它对我的问题有什么帮助。在拦截器中,您仍然没有有关响应的信息。 (2认同)
  • 不,用户没有被重定向。我在 angularjs 中发出 HTTP 请求(使用 $http),并得到错误响应。没有其他事情发生。 (2认同)