What is Cross Origin Resource Sharing (CORS) and How Does It Work?

Table of contents

Have you ever encounter CORS errors while integrating api into your front end apps. You would be wondering “what did i do wrong?”. Relax it’s not your fault. It’s not even a client code error. CORS errors cannot be accessed or resolved programmatically in client-side code. To diagnose them, you must inspect the browser’s network tab, where the blocked request will explicitly show CORS-related headers and errors. It’s because of the configuration that need to be updated in the server side. Before talking about updating the server side configuration, let’s deep into CORS.
What is CORS?
As the name, Cross Origin Resource Sharing, suggests it allows web server to describe which domain, port or method are allows to request its data from a web browser. Normally, browsers don’t allow app to fetch data from other sources other than its own origin where the app launch unless the requested source ( server ) describe that it allows requests from the app (client). For that browser automatically send an OPTIONS
request with HTTP Headers and wait for the response from the server. If the response return with 2xx and includes headers such as Access-Control-Allow-Origin:
https://yourdomain.org
, you are good to go and your actual request will send to the server. CORS errors can’t be access from code so you have to check for browser network tab to see the CORS error.
CORS Headers
Access-Control-Allow-Origin: “https://domain-a.com”
This is the header to specify which origin are allowed to request data from it. You can use asterisk for wild card which means every domain can request data from it
Access-Control-Allow-Methods:['GET', 'POST']
This is the header to specify which HTTP methods are allow to make from the allowed origin.
Access-Control-Allow-Headers: ['Content-Type', 'Authorization']
This is to specify which HTTP headers are allowed to include in requests
Access-Control-Allow-Credentials: true
This header specify if the requests will include credentials such as cookies. By default browser will not send the credential along. So its default value is
false
. If you set theAccess-Control-Allow-Credentials
totrue
, you can’t use wildcard(*) anymore. You have to specify all the allowed origins specifically.Access-Control-Max-Age: 86400
After successfully completing a preflight request, its response is cached automatically without sending another value. This header is to define the cache lifetime in seconds. Default is 5 seconds.
How To Solve CORS error?
If you are front end developer who don’t have access to backend code, you can use a proxy server to send a request in behalf of your app. If you are a backend developer, here is how to accept request from cross origins. In Javascript world, there is always at least one package for everything. There is also one for cors headers called cors
. I am using it in the example.
const express = require('express');
const cors = require('cors');
const app = express();
// Basic CORS configuration (least restrictive - development only)
app.use(cors());
// Advanced CORS configuration (production-ready example)
const allowedOrigins = [
'https://yourdomain.com',
'http://localhost:3000',
'https://yourapp.vercel.app'
];
const corsOptions = {
origin: function (origin, callback) {
if (allowedOrigins.indexOf(origin) !== -1 || !origin) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 86400
};
// Use advanced configuration
app.use(cors(corsOptions));
I used to face CORS error a lot. So i decided to write explaining about it. Hope you guys find this hopeful. Happy Coding.
References:
Subscribe to my newsletter
Read articles from Han Lin Aung directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
