I'm developing an Angular2 application. It seems when my access-token expires the 401 HTTP Status code gets changed to a value of 0 in the Response object. I'm receiving 401 Unauthorized yet the ERROR Response object has a status of 0. This is preventing me from trapping a 401 error and attempting to refresh the token. What's causing the 401 HTTP status code to be changed into HTTP status code of 0?
Here's screenshot from Firefox's console:
Here's my code:
get(url: string, options?: RequestOptionsArgs): Observable<any>
{
//console.log('GET REQUEST...', url);
return super.get(url, options)
.catch((err: Response): any =>
{
console.log('************* ERROR Response', err);
if (err.status === 400 || err.status === 422)
{
return Observable.throw(err);
}
//NOT AUTHENTICATED
else if (err.status === 401)
{
this.authConfig.DeleteToken();
return Observable.throw(err);
}
else
{
// this.errorService.notifyError(err);
// return Observable.empty();
return Observable.throw(err);
}
})
// .retryWhen(error => error.delay(500))
// .timeout(2000, new Error('delay exceeded'))
.finally(() =>
{
//console.log('After the request...');
});
}
This code resides in a custom http service that extends Angular2's HTTP so I can intercept errors in a single location.
In Google Chrome, I get this error message:
XMLHttpRequest cannot load https://api.cloudcms.com/repositories/XXXXXXXXXXXXXXXX/branches/XXXXXXXXXXXXXXXX/nodesXXXXXXXXXXXXXXXX. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://screwtopmedia.local.solutiaconsulting.com' is therefore not allowed access. The response had HTTP status code 401.
This is confusing because I am including 'Access-Control-Allow-Origin' header in request.
Here's a picture of results received in Google Chrome:
I've tried accessing 'WWW-Authenticate' Response Header as a means to trap for 401. However, the following code returns a NULL:
err.headers.get("WWW-Authenticate")
It's puzzling that I'm getting a CORS issue because I'm not getting any CORS errors when a valid access token is provided.
How do I trap for 401 HTTP status code? Why is 401 HTTP status code being changed to 0?
Thanks for your help.
I work for Cloud CMS. I can confirm that we properly set CORS headers on API calls. However, for 401 responses the headers are not getting set properly. This has been resolved and the fix will be available on the public API at the end of this week.
BTW if you use our javascript driver https://github.com/gitana/gitana-javascript-driver instead of writing to the API directly then the re-auth flow is handled automatically and you do not need to trap 401 errors at all.
According to W3C, if the status attribute is set to 0, it means that:
or
I think that this isn't an
Angular2
issue, it seems like your request has a problem.If cloudcms.com do to not set the
Access-Control-Allow-Origin
in 401 response, then nothing much you can do. You properly have to open support ticket with them to confirm if that is normal behavior.javascript in browsers(FF, Chrome & Safari) I tested won't receive any info if CORS error occur, other than status 0. Angular2 has no control of it.
I created a simple test and get the same result as yours:
After much googling, I found the following(https://github.com/angular/angular.js/issues/3336):
Result from Firefox network monitor seems supporting the above reason.
Javascript request will receive empty response.
Plain url request(copy&paste the link in the address bar) will get response body
Javascript use XHRHttpRequest for http communication.
When a XHR reply arrive, the browser will process the header, that's why you will see those 401 network messages. However, if the XHR reply is from a different host then the javascript AND the response header contain no CORS header(eg
Access-Control-Allow-Origin: *
), the browser will not pass any info back to the XHR layer. As a result, the reply body will be completely empty with no status(0).I tested with FF 48.0.1, Chrome 52.0.2743.116 and Safari 9.1.2, and they all have the same behavior.
Use browser network monitor to check response header for those
401 Unauthorized
entries, it is very likely that there is noAccess-Control-Allow-Origin
header and causing the issue you are facing. This can be a bug or by design on the service provider side.Access-Control-Allow-Origin
is a response only http header. For more information of https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#The_HTTP_response_headersI had the same issue and was due to the server not sending the correct response (even though the console log stated a 401 the Angular error had status 0). My server was Tomcat with Java application using Spring MVC and Spring Security.
It is now working using folowing setup:
SecurityConfig.java
SomeAuthenticationEntryPoint.java
web.xml
Controller to handle the /errors/... previously defined
You should use a 3rd party http protocol monitor (like CharlesProxy) rather than Chrome dev tools to confirm which headers are actually being sent to the API service and if it is returning a 401.
The issue is related to CORS requests, see this github issue
means that
'Access-Control-Allow-Origin'
is required in the response headers.Angular is not getting any status codes, that's why it gives you a
0
which is caused by browser not allowing thexml parser
to parse theresponse
due to invalidheaders
.You need to append correct CORS headers to your
error response
as well assuccess
.