by Sai gowtham

A beginners guide to cross origin resource sharing (CORS)

In this tutorial, we are going to learn about what is cross-origin resource sharing(cors) and how to resolve the cors errors.

What is CORS ?

Cross-origin resource sharing is a security mechanism that prevents you accessing website resources from the different domains or subdomains.

For example, If we try to fetch a data from the example.com to example-24.com you will get a cors error because the origin URL is example.com and you are making the http request to example-24.com.

The origin URL example.com !== example-24.com so that the cross-origin resource sharing policy doesn’t allow you to make http requests to that API endpoint.

Let’s learn it by using an real example.

We are creating a sample server using node and express.

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

app.get('/hello', (req, res) => {
    res.json({ name: "reactgo", up: true })
})

app.listen(3000, () => {
    console.log('server is up')
})

Now if we open localhost:3000/hello in our browser it will respond with the json object.

cors example

Cors error

Now, we are fetching the data from the different origin in our frontend app by making an http request to our endpoint localhost:3000/hello.

fetch("http://localhost:3000/hello")
  .then(function(response) {
     return response.json()
  }).then(data=>{
    console.log(data)
  })
  .catch(function(err) {
    console.log(err);
  });

Output

cors http error example

The error is clearly mentioning you are making an http request from the different origin

In the above code, the error has occurred because the user agent made an http request from https://codesandbox.io/s/3884xqz4lm origin to http://localhost:3000/hello so that the response comes the localhost:3000/hello doesn’t contain ‘Access-control-allow-origin’ header.

If the response doesn’t contain ‘Access-control-allow-origin’ header then our user-agent invoke the err callback function.

If the response contains ‘Access-control-allow-origin’ header then our user-agent invoke the response callback function.

How to resolve the cors error?

To resolve the cors error we need to add the Access-Control-Allow-Origin header to our response.

Let’s add the Acess-control-Allow-Origin header to our server.

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

app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    next();
});


app.get('/hello', (req, res) => {
    res.json({ name: "reactgo", up: true })
})

app.listen(3000, () => {
    console.log('server is up')
})

We added a middleware to our express server, so that for every response we are sending an Access-Control-Allow-Origin header to the client.

"Access-Control-Allow-Origin", "*"

* is a wildcard character it means we can fetch the data from the any origin.

Let’s test our API endpoint.

cors error resolved

If you open your network tab in chrome dev tools you will see a Request headers and Response headers.

Response headers

Access-Control-Allow-Origin: *
Connection: keep-alive
Date: Sat, 05 Jan 2019 01:14:49 GMT
ETag: W/"1c-tkTgCcXUYKqMoGefdC0jm6oVXk8"
X-Powered-By: Express

Request headers

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: keep-alive
Host: localhost:3000
If-None-Match: W/"1c-tkTgCcXUYKqMoGefdC0jm6oVXk8"
Origin: https://3884xqz4lm.codesandbox.io

How to allow requests only from particular origins?

Sometimes we need to allow requests only from particular origins in that cases we need to specify the origins instead of adding wild * card character.

The express framework provides us a cors middleware which helps us to easily enable the cors.

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


var corsOptions = {
    origin: 'https://3884xqz4lm.codesandbox.io',
    optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}

app.use(cors(corsOptions))

app.get('/hello', (req, res) => {
    res.json({ name: "reactgo", up: true })
})

app.listen(3000, () => {
    console.log('server is up')
})

if we want to allow more than one origin we can do that by passing our origins in an array.

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

const  whitelist = ['https://3884xqz4lm.codesandbox.io',
                     'http://example2.com']

const  corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}

app.use(cors(corsOptions));

app.get('/hello', (req, res) => {
    res.json({ name: "reactgo", up: true })
})

app.listen(3000, () => {
    console.log('server is up')
})

What is a preflight request?

Preflight request is an http request issued by the browsers automatically to check whether the requested API endpoint is participating in the cors protocol by including an origin header.

A CORS-preflight request is a CORS request that checks to see if the CORS protocol is understood. It uses OPTIONS as the method and includes these headers:

The options method contain

Access-Control-Request-Method Indicates that which http method might use when a actual request is made.

Access-Control-Request-Headers Indicates that which http headers the client might send to the server when a actual request is made.

For example, a client is asking a server if POST request is allowed before sending a actual POST request, by using a preflight request.

OPTIONS /user/123
Access-Control-Request-Method: POST
Access-Control-Request-Headers: origin, x-requested-with
Origin: https://example.org

Response from the server

HTTP/1.1 200 OK
Connection: keep-alive
Access-Control-Allow-Origin: https://example.org
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 63400

The Acess-control-Allow-origin-Methods tell us we can also make GET and DELETE requests.

Access-Control-Max-Age: It tells us how long the information provided by the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers can be cached.

Top Udemy Courses

JavaScript - The Complete Guide 2020 (Beginner + Advanced)
JavaScript - The Complete Guide 2020 (Beginner + Advanced)
45,614 students enrolled
52 hours of video content
View Course
React - The Complete Guide (incl Hooks, React Router, Redux)
React - The Complete Guide (incl Hooks, React Router, Redux)
284,472 students enrolled
40 hours of video content
View Course
Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)
Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)
130,921 students enrolled
21 hours of video content
View Course