Javascript http request: No 'Access-Control-Allow-Origin' header is present on the requested resource error

Created:

Introduction

When you are developing a web application that tries to access another domain using javascript for querying an API RestFUL, it common to get the following error:

XMLHttpRequest cannot load http://anotherdomain.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

Important: This error occurs when the client URL and server URL don't match, including the port number.

This is security protection on the browsers and it's expected behavior. You can use XMLHttpRequest to receive and send data to remote servers, but it's limited by the same origin policy. The same-origin policy means that requests can only be made to the same domain and not another one.

The proper way to solve this issue is using Cross-Origin Resource Sharing (CORS). We are going to see in this tutorial how to fix the error "'Access-Control-Allow-Origin' header is present on the requested resource".

We are not going to cover using JSONP or build a custom proxy, but those two are other possible solutions.

Solution using CORS headers

First, you need to understand CORS. The key point is that the other domain will add headers to the response and this will allow the browser to execute the XMLHttpRequest. You will need to make changes on the other server to add those response headers. Usually, frameworks like Django or Flask support CORS, and is pretty easy to add those headers.

For the next solutions, we assume that your server will return the right headers for accepting the requests from another domain you trust. Remember! other domains that you trust!

For example, with Nginx:

add_header Access-Control-Allow-Origin http://localhost:3000

You can check the headers of your server using

curl -H https://server_address

It's very common to have this error with the OPTIONS method, you can change the method while using curl with the parameter -X OPTIONS.

In the past doing a CORS request with javascript was tricky, today you can use Axios or the mozilla Fetch API. We will cover some examples with different libraries

Vanilla javascript

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://mywebsite.com', true);
xhr.withCredentials = true;
xhr.onreadystatechange = function() {
    if (xhr.readyState === 2) {// do something}
}
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(json);

Making CORS with jquery

You can use ajax function to make the request to another domain (which will have the appropiate headers). Note that the difference here is:

xhrFields: {
    withCredentials: true
},

Full example on how to make a http request using CORS with jquery:

$.ajax({
    url: url,
    type: method,
    // This is the important part
    xhrFields: {
        withCredentials: true
    },
    // This is the important part
    data: data,
    success: function (response) {
        // handle the response
    },
    error: function (xhr, status) {
        // handle errors
    }
});

Using Axios

Here is an example on how to make a CORS request using axios:

axios.get('http://localhost', {
    withCredentials: true,
}).then(res => { 
    console.log(res);
}).catch(error => {
    console.log('erro', error);
})

If the error continues to appear and your server is returning CORS headers on the response, make sure your server also answers to OPTIONS request. Axios first makes an OPTIONS request and if it fails it will not do any other request. It's common to just implement the GET or POST and backend developers usually forgot about the OPTIONS.

Using Mozilla Fetch

Here we are making a CORS request using Mozilla fetch API:

var headers = new Headers();

var requestOptions = { 
    method: 'GET',
    headers: headers,
    mode: 'cors',
    cache: 'default' 
};

fetch('example.jpg',requestOptions)
.then(function(response) {
  return response.blob();
})
.then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  image.src = objectURL;
});

As you can see options set mode cors to make the CORS request.

Conclusion

CORS error can be a pain for developers. Make sure you understand the same-origin policy and how it avoids a forgery attack. When you want to do a request to another domain you need to add the proper headers, make sure you understand what you are doing. Using a library like Axios will make your code easier to understand.