Explaining How CORS Works – What You Need To Understand

Avatar photo

By George

6 min read
Bookmark this post

In this post, we’ll try and understand how CORS works, how to configure an Express.js server to support CORS and test it using our browser tools. Understanding CORS is crucial for web developers so let’s break it down and get started!!

What is CORS?

CORS, or Cross-Origin Resource Sharing, is a set of rules that allow or restrict the sharing of resources between servers and browsers. Who is responsible, though, for setting up the rules? The server makes the rules, and it’s up to the browser to follow them. Let’s simplify by using an example.

We have a browser loading a page at https://noghostsinside.com.

This page has a script to be loaded, and because of this, the browser sends a request to a server located at https://api.noghostsinside.com.

When sending the request, the browser adds an “Origin” header stating the protocol, host, and port (optional) from which the request is made. In our example, it would be Origin: https://noghostsinside.com.

Browser sending request to server

When the server receives this request, it will respond with a header called Access-Control-Allow-Origin.

Server responding to browser

This header will include all origins that are allowed to load the requested resource; examples of this header’s value could be:

  • Access-Control-Allow-Origin: * – All origins are allowed to load this resource.
  • Access-Control-Allow-Origin: "https://noghostsinside.com" – Only requests from this URL are allowed to load this resource.

There is also a chance that there will be no Access-Control-Allow-Origin header, included in the server’s response headers. The lack of this header makes the browser assume that resource sharing is only allowed from requests from within the same origin – known as Same-origin policy.

When testing your site’s server interaction, there is a good chance you are doing it without using the browser. If you’re using a program like Postman, CORS isn’t automatically applied. This means you might be able to load resources without restriction. To ensure compliance with CORS policies, configure your program to behave like a browser.

Non-browser HTTP clients typically don’t apply CORS unless specifically configured to do so.

How CORS works: exploring with dev tools

To see CORS in action, I have set up a simple server on my machine using Express.js. It responds with a simple object on the / route.

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

app.get('/', (req, res) => {
  res.send({
    name: 'No Ghosts Inside'
  });
})

app.listen(PORT, () => {
  console.log(`Your app is listening on port ${PORT}`);
})

JavaScript

After running this server, I opened my browser in noghostsinside.com blog (not my localhost) and accessed the dev-tools console tab. From there, I executed the following command:

Console
fetch("http://localhost:8080")
      .then(res => res.json())
      .then(data => console.log({ data }))

This command fetches data from my local server running on port 8080 and logs its response in the console. In case you didn’t already know, by executing this command, I got a CORS error:

If you remain calm when reading this error 😩, it is probably straightforward to understand that we cannot load resources requested from (origin) https://noghostsinside.com to http://localhost:8080/ because we are blocked by CORS.

This error also provides us with another piece of information, for solving our problem. What piece of information is that? The response is missing the Access-Control-Allow-Origin header.

I decided to investigate further by navigating to my Network tab, and in the list of Names, I clicked where it said “localhost.” Checking in the Headers tab in the Request Headers section, I found the Origin header set to https://noghostsinside.com but nothing about Access-Control-Allow-Origin in the Response Headers.

Request from browser send to server with Request Headers - Origin set to "https://noghostsinside.com" - screenshot from devtools

Because we don’t have Access-Control-Allow-Origin setup, as mentioned at the beginning of this post, our browser respects the Same-origin policy and doesn’t let us load resources from localhost. To overcome this obstacle we need to tell the server to allow access to resources provided by the `/` endpoint to our origin. Let’s proceed and do that.

How to configure CORS to your Express.js server

Remember that we have not set anything on the server side about CORS, right? Express.js suggests using a node package named cors when dealing with CORS issues.

Let’s first install it (--save flag is not needed anymore for saving dependencies)

npm install cors
Bash

and change our code, based on the cors‘s documentation, to

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

app.use(cors());

app.get('/', (req, res) => {
  res.send({
    name: 'No Ghosts Inside'
  });
})

app.listen(PORT, () => {
  console.log(`Your app is listening on port ${PORT}`);
})
JavaScript

So we are just adding cors to be used by our application, right? Alright, but how can we validate it worked?

I returned to my browser and ran the fetch command I ran earlier. This time I got back a response!

Console
{
    "data": {
        "name": "No Ghosts Inside"
    }
}

That’s great! The CORS issue is solved, but it would be nice to know if something happened in the response’s headers, too, right?

By visiting the Network tab for localhost now, I saw indeed the Access-Control-Allow-Origin header added in the response and an * as its value. Having an * as its value implies that the browser can access a resource from any origin.

Defining explicit CORS origin

Great? I mean, yeah, we have solved the CORS issue, but do we want to give access to resources from all origins? No right? It’s best to clearly state what we want by using the cors package to set a specific URL in the header. We can do this by changing our code to

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

app.use(cors({
  origin: 'https://noghostsinside.com',
}));

app.get('/', (req, res) => {
  res.send({
    name: 'No Ghosts Inside'
  });
})

app.listen(PORT, () => {
  console.log(`Your app is listening on port ${PORT}`);
})
JavaScript

By doing so, the header value will also change to Access-Control-Allow-Origin: https://noghostsinside.com and we will now have explicitly allowed cross-origin resources access only to our blog. Well done! 😎 🥳

Request from browser send to server with Response Headers - Access Control Allow Origins set to "https://noghostsinside.com" - screenshot from devtools
DigitalOcean Referral Badge
guest
0 Comments
Inline Feedbacks
View all comments

Continue reading

Front, Programming

Learn How to Select Only the CSS First Child

Front, Programming

The CSS nth-of-type Selector – How To Target Elements By Type

Front, Programming

What You Need to Know About CSS nth child Selector – A Practical Guide

Front, Programming

CSS Selectors nth-child VS nth-of-type And How To Use Them Correctly

Front, Programming

Coding Made Easy With CSS Selectors: An Ultimate Guide

Front, Programming

How to Center in CSS Using Different Ways

Front, Programming

What You Need to Know About CSS Color Methods

Programming

Most Common Typescript Errors and How to Solve Them

Front, Programming

Make Your Work Easier by Using Variables in CSS

Front, Programming

CSS Rainbow Text: How To Make Astonishing And Vibrant Fonts

Front, Programming

Most Useful HTML Elements for Maximizing Better Results

Back, Programming

Environment Variables 101: Secure Your Secrets Like a Pro

Subscribe to our newsletter

Dive into the Fun Side of Tech! Posts, News, and More Delivered to Your Inbox!

Intuit Mailchimp