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
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):
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.
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?
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
You can follow these five steps to fix HTTP 302 errors on your website: Determine whether the redirects are appropriate or not by examining the URLs that are issuing the 302 redirects. Check your plugins to make sure any redirect settings are valid. Ensure that your WordPress URL settings are configured correctly.
The HyperText Transfer Protocol (HTTP) 302 Found redirect status response code indicates that the resource requested has been temporarily moved to the URL given by the Location header.
If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
get Method. In angularjs $http service is used to send or get data from remote http servers using browsers XMLHttpRequest object. In angularjs $http service is having many shortcut methods available like $http.
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.
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
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.
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');
good luck.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With