Access Control Origin Header error using Axios

I’ll have a go at this complicated subject.

What is origin?

The origin itself is the name of a host (scheme, hostname, and port) i.g. https://www.google.com or could be a locally opened file file:// etc.. It is where something (i.g. a web page) originated from. When you open your web browser and go to https://www.google.com, the origin of the web page that is displayed to you is https://www.google.com. You can see this in Chrome Dev Tools under Security:

The same applies for if you open a local HTML file via your file explorer (which is not served via a server):

What has this got to do with CORS issues?

When you open your browser and go to https://website.example, that website will have the origin of https://website.example. This website will most likely only fetch images, icons, js files and do API calls towards https://website.example, basically it is calling the same server as it was served from. It is doing calls to the same origin.

If you open your web browser and open a local HTML file and in that HTML file there is JavaScript which wants to do a request to Google for example, you get the following error:

The same-origin policy tells the browser to block cross-origin requests. In this instance origin null is trying to do a request to https://www.google.com (a cross-origin request). The browser will not allow this because of the CORS Policy which is set and that policy is that cross-origin requests is not allowed.

Same applies for if my page was served from a server on localhost:

Localhost server example

If we host our own localhost API server running on localhost:3000 with the following code:

const express = require('express')
const app = express()

app.use(express.static('public'))

app.get('/hello', function (req, res) {
    // res.header("Access-Control-Allow-Origin", "*");
    res.send('Hello World');
})

app.listen(3000, () => {
    console.log('alive');
})

And open a HTML file (that does a request to the localhost:3000 server) directory from the file explorer the following error will happen:

Since the web page was not served from the localhost server on localhost:3000 and via the file explorer the origin is not the same as the server API origin, hence a cross-origin request is being attempted. The browser is stopping this attempt due to CORS Policy.

But if we uncomment the commented line:

const express = require('express')
const app = express()

app.use(express.static('public'))

app.get('/hello', function (req, res) {
    res.header("Access-Control-Allow-Origin", "*");
    res.send('Hello World');
})

app.listen(3000, () => {
    console.log('alive');
})

And now try again:

It works, because the server which sends the HTTP response included now a header stating that it is OK for cross-origin requests to happen to the server, this means the browser will let it happen, hence no error.

How to fix things (One of the following)

  • Serve the page from the same origin as where the requests you are making reside (same host).
  • Allow the server to receive cross-origin requests by explicitly stating it in the response headers.
  • If using a reverse proxy such as Nginx, configure Nginx to send response headers that allow CORS.
  • Don’t use a browser. Use cURL for example, it doesn’t care about CORS Policies like browsers do and will get you what you want.

Example flow

Following is taken from: Cross-Origin Resource Sharing (CORS)

Remember, the same-origin policy tells the browser to block
cross-origin requests. When you want to get a public resource from a
different origin, the resource-providing server needs to tell the
browser “This origin where the request is coming from can access my
resource”. The browser remembers that and allows cross-origin resource
sharing.

  • Step 1: client (browser) request When the browser is making a cross-origin request, the browser adds an Origin header with the
    current origin (scheme, host, and port).

  • Step 2: server response On the server side, when a server sees this header, and wants to allow access, it needs to add an
    Access-Control-Allow-Origin header to the response specifying the
    requesting origin (or * to allow any origin.)

  • Step 3: browser receives response When the browser sees this response with an appropriate Access-Control-Allow-Origin header, the
    browser allows the response data to be shared with the client site.

More links

Here is another good answer, more detailed as to what is happening: https://stackoverflow.com/a/10636765/1137669

Leave a Comment