在 angularjs 中处理来自代理的 HTTP 302 响应 [英] Handle HTTP 302 response from proxy in angularjs

查看:82
本文介绍了在 angularjs 中处理来自代理的 HTTP 302 响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a reverse proxy that checks global authentication for several applications. When the user is disconnected but still trying to use my application, the proxy sends a 302 response :

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

在 angularJs 中,错误回调被调用,但响应头为空,状态为 0,数据为空字符串.所以看起来我真的无能为力来处理响应......
我已经看到了几个关于这个主题的问题,但我仍然不明白发生了什么(CORS 因为代理或位置不同的域?,302 浏览器行为?).
特别是答案中的这一部分(https://stackoverflow.com/a/17903447/1093925):

In angularJs, the error callback is called but the response headers are empty, status is 0 and data is an empty string. So it seems that I really can't do nothing to handle the response...
I've seen several questions on the subject, and I still don't understand what is going on (CORS because of the proxy or different domain in the location?, 302 browser behavior?).
In particular there is this part from an answer (https://stackoverflow.com/a/17903447/1093925):

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

Note: If your server sets a response code of 301 or 302, you will not be able to get the Location header, as it will be automatically and transparently followed by the XMLHttpRequest object.

这个 XMLHttpRequest 对象怎么样?
在非常旧版本的 Chrome(无法使用较新版本)中,我可以在网络面板中看到相应的请求,但由于没有响应,它似乎失败了.
在最新版本的 Firefox 中,什么也没有发生.

What about this XMLHttpRequest object?
In a very old version of Chrome (can't use a newer version) I can see that a corresponding request in the network panel, but it seems to fail as there is no response.
In the latest version of firefox, there is nothing going on.

因为我无法更改代理配置和响应,所以我可以做些什么吗?

Can I do anything about that, since I can't change the proxy configuration and response?

更新:
我今天重播了我的场景,多亏了更新版本的 firebug,我能够获得更多关于正在发生的事情的详细信息.
我的问题离答案不远:跨域策略.
由于它是我的应用程序发出的 HTTP 请求,浏览器拒绝以下 XMLHttpRequest(应用程序内看起来像相同的请求).因此出现错误和空响应.
所以我觉得我没有什么特别可以做的

Update:
I replayed my scenario today, and thanks to a newer version of firebug, I was able to get more details about what is going on.
I was not far from the anwser in my question : Cross domain policy.
Since it is an HTTP request made by my application, the browser denies the following XMLHttpRequest (which in-app looks like the same request). Hence the error and the empty response.
So I think there is nothing special I can do about it

推荐答案

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

I had the same problem in my app. You can't really "catch" a 302 redirect response. The browser catches it before Angular get it's hand on it. so actually, when you do receive your response - it is already too late.

坏消息:在 Angular 平台中这不是问题.xmlHttpRequest 不支持这种行为,浏览器会在您对此做任何事情之前采取行动.参考:防止 Xmlhttprequest 的重定向

The bad news: it's not a problem in the angular platform. The xmlHttpRequest do not support this kind of behaviour, and the browser act before you can do anything about it. reference: Prevent redirection of Xmlhttprequest

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

The good news: there are many ways to bypass this problem, by intercepting the response- and find some way to recognize that it's your lovable 302. This is a hack, but it's the best you can do at the moment.

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

So. For example, in my app, the redirect was back to the login.html page of the app, and in the app i got the response with a 200 status and the data of the response was the content of my login.html page. so in my interceptor, i checked if the result is a string (usually not! so- no efficiency prob..) and if so- checked if it's my login.html page. that way, i could catch the redirect and handle it my way.

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;
    };
}]);

然后将此拦截器插入到您的应用程序中.像这样:

Then insert this interceptor to your app. something like this:

$httpProvider.responseInterceptors.push('redirectInterceptor');

祝你好运.

这篇关于在 angularjs 中处理来自代理的 HTTP 302 响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆