Saturday, April 6, 2019

Handle HTTP 302 response from proxy in Angular

HTTP 302 responses, aka redirects, are not available to Angular as xmlHttpRequest does not support returning redirects; the browser acts before you can do anything about it.


If the response is an HTTP redirect:

If the origin of the URL conveyed by the Location header is same origin with the XMLHttpRequest origin and the redirect does not violate infinite loop precautions, transparently follow the redirect while observing the same-origin request event rules.
refernce: stackoverflow


To act upon  a 302 response, 

You could check for specific data responses, or worse, override the status code 302 with a status code that is returned, such as 403, and act upon that.


X-Redirect header

However, a more generic solution is to add a custom redirect header, such as `X-Redirect` and act upon that. The value of `X-Redirect` should be the url you want to redirect to eg https://other.url.com/page

An $http example:
$http.get(orig_url).then(function(response) {
        // do stuff
    }, function (response) {
        var headers = response.headers();
        if ('x-redirect' in headers)
        {
            document.location.href = headers['x-redirect'];
        }
        return response;
    }
}

For a more global solution, you could also use a HTTP Interceptor:
app.factory('myHttpInterceptor', function ($q, myCache) {
    return {
        request: function (config) {
            return config;
        },
        response: function(response){
            var headers = response.headers();
            if ('x-redirect' in headers)
            {
                document.location.href = headers['x-redirect'];
            }    
            return response;
        },
        responseError: function(rejection) {    
            switch(rejection.status)
            {
                case 302:
                    // this will not occur, use the custom header X-Redirect instead
                    break;
                case 403:
                    alert.error(rejection.data, 'Forbidden');
                    break;
            }
            return $q.reject(rejection);
        }
    };
});

You can set the custom header server side.
For example, if you are using PHP Symfony:

$response = new Response('', 204);
$response->headers->set('X-Redirect', $this->generateUrl('other_url'));
return $response;

-End of Document-
Thanks for reading

1 comment: