HVRDHVRD
ExpressJS

CORS

In-depth guide to understanding, configuring, and handling CORS in web applications and ExpressJS servers.

CORS (Cross-Origin Resource Sharing)

CORS stands for Cross-Origin Resource Sharing. It's a security feature implemented by browsers that controls how resources are requested from a different origin (domain, protocol, or port) than the one serving the web page.


Why Does CORS Matter?

Web browsers enforce the Same-Origin Policy (SOP) to prevent malicious scripts on one site from accessing sensitive data on another. By default, web applications running in a browser can only make HTTP requests to the same origin.

However, legitimate cases exist where applications need to request resources from other origins. This is where CORS comes into play — it allows controlled cross-origin access.


How CORS Works

When a web page makes a cross-origin HTTP request (e.g., using fetch or XMLHttpRequest), the browser automatically sends an Origin header.

Example request from https://frontend.com to https://api.example.com/data:

GET /data HTTP/1.1
Host: api.example.com
Origin: https://frontend.com

Server Response Example Allowing Access

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://frontend.com
Content-Type: application/json

If the response includes the proper Access-Control-Allow-Origin header, the browser allows the frontend to access the response.


Preflight Requests

For certain HTTP methods (e.g., PUT, DELETE) or when using custom headers, the browser sends an OPTIONS preflight request first to verify if the server allows the actual request.

Preflight Request Example

OPTIONS /data HTTP/1.1
Host: api.example.com
Origin: https://frontend.com
Access-Control-Request-Method: PUT

Server Preflight Response Example

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization

Configuring CORS in ExpressJS

The easiest way to handle CORS in Express is to use the cors middleware from npm.

Basic Setup: Allow All Origins

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

app.use(cors());

app.get('/public-data', (req, res) => {
  res.json({ message: 'Accessible from any origin' });
});

app.listen(3000);
  • This allows all origins (*) by default.

Restricting Allowed Origins

app.use(cors({
  origin: 'https://frontend.example.com'
}));

Only requests from https://frontend.example.com will be allowed.


Enabling Specific Methods and Headers

app.use(cors({
  origin: 'https://frontend.example.com',
  methods: ['GET', 'POST'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));

This configures CORS to only allow the specified HTTP methods and headers.


Handling Preflight Requests

The cors middleware handles preflight OPTIONS requests automatically.

If needed, manually handle it:

app.options('/data', cors()); // Enable preflight for /data route

Custom CORS Middleware Example

function customCors(req, res, next) {
  const allowedOrigins = ['https://example.com', 'https://another.com'];
  const origin = req.headers.origin;

  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }

  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');

  if (req.method === 'OPTIONS') {
    return res.sendStatus(204);
  }

  next();
}

app.use(customCors);

Common Issues

  • Missing Access-Control-Allow-Origin header → Browser blocks the response.
  • Using * for Access-Control-Allow-Origin disallows sending credentials (cookies, auth headers).
  • Preflight failure → Happens when server doesn’t respond properly to OPTIONS requests.

Best Practices

  • Limit allowed origins to trusted domains.
  • Use specific methods and headers instead of allowing everything.
  • Avoid using * in production unless intended for public APIs.
  • Ensure preflight requests are handled properly.
  • Monitor and log CORS errors during development.