Today I found a strange behavior of XMLHttpRequest. When I am calling a GET service I found that if I do not set the Authorization header the request from firefox is same. But if I add the "Authorization" header firefox first send a request with "OPTIONS" then it sends a "GET" request.
I know that the verb "OPTIONS" must be handled in server side but I was just wondering why XMLHttpRequest behaves like this. Though it is a cross domain request, why browser first send the "OPTIONS" request. Why adding a "Authorization" header changes the behavior.
Here is my Javascript code and Fidler Inspector report.
var xmlhttp = new XMLHttpRequest();
var url = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
xmlhttp.open('GET',url,true);
xmlhttp.setRequestHeader("Authorization", "xxxxxxxxxxxxxxxxxxx");
xmlhttp.send(null);
xmlhttp.onreadystatechange = function() {
alert("OnReadystatechange + " + xmlhttp.readyState + " " + xmlhttp.status);
if (xmlhttp.readyState == 4) {
if ( xmlhttp.status == 200) {
}
else {
}
}
else
alert("Error ->" + xmlhttp.responseText);
}
And the fiddler response with Authorization Header
But when I do not add the Authorization header the browser directly sends the GET request no OPTIONS request.
The XMLHttpRequest method setRequestHeader() sets the value of an HTTP request header. When using setRequestHeader() , you must call it after calling open() , but before calling send() . If this method is called several times with the same header, the values are merged into one single request header.
The Authorization header is usually, but not always, sent after the user agent first attempts to request a protected resource without credentials. The server responds with a 401 Unauthorized message that includes at least one WWW-Authenticate header.
To send a GET request with a Bearer Token authorization header, you need to make an HTTP GET request and provide your Bearer Token with the Authorization: Bearer {token} HTTP header.
It is indeed not possible to pass the username and password via query parameters in standard HTTP auth. Instead, you use a special URL format, like this: http://username:[email protected]/ -- this sends the credentials in the standard HTTP "Authorization" header.
The HTTP OPTIONS
request is used to "preflight" the cross-origin GET
request, before actually sending it.
Unlike simple requests, "preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if:
- It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than
application/x-www-form-urlencoded, multipart/form-data, or
text/plain, e.g. if the POST request sends an XML payload to the
server using application/xml or text/xml, then the request is
preflighted.- It sets any header that is not considered simple. A header is said to be a simple header if the header field name is an ASCII case-insensitive match for Accept, Accept-Language, or Content-Language or if it is an ASCII case-insensitive match for Content-Type and the header field value media type (excluding parameters) is an ASCII case-insensitive match for application/x-www-form-urlencoded, multipart/form-data, or text/plain.
So in your case, setting the Authorization header is causing the request to be preflighted, hence the OPTIONS
request.
More info here
Spec on Cross-Origin Request with Preflight
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