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

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.

This is a security protection on the browsers and it's an expected error. You can use XMLHttpRequest to receive and send data to remove server, but it's limited by the same origin policy. Same origin policy means that request can only be made to the same domain an 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 possible solutions.

Using CORS

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 supports CORS or is pretty easy to add those headers.

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 usua;;y 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 ca see options set mode cors to make the CORS request.