The Developer's Guide to CORS: Resolving Cross-Origin Requests Securely
Learn how the browser's Same-Origin Policy works, understand HTTP preflight OPTIONS requests, and discover how to configure CORS headers securely in Node.js and Python.
The Developer's Guide to CORS: Resolving Cross-Origin Requests Securely
If you've built a web application, you've almost certainly encountered this browser error:
Access to fetch at 'https://api.domain.com/data' from origin 'https://app.domain.com' has been blocked by CORS policy.
CORS (Cross-Origin Resource Sharing) is a critical web security mechanism, not a bug. In this developer guide, we'll demystify how CORS works, explore the browser's preflight request sequence, and configure secure headers.
🔒 Same-Origin Policy: The Security Sandbox
CORS exists because of the browser's Same-Origin Policy (SOP). SOP restricts scripts running on one website from reading data from another website.
An "Origin" is defined by three components:
1. Protocol (e.g., http vs https)
2. Domain / Host (e.g., domain.com vs api.domain.com)
3. Port (e.g., :80 vs :3000)
If any of these three elements differ between the requester and the destination, the request is considered Cross-Origin.
🚦 Simple Requests vs. Preflight Requests
When a browser makes a cross-origin request, it classifies it into one of two categories:
1. Simple Requests
Requests that do not trigger a preflight check. They must meet all of the following conditions:
* HTTP Methods: GET, POST, or HEAD.
* Allowed Headers: Only standard headers like Accept, Accept-Language, Content-Language, or Content-Type.
* Content-Type value: Limited to application/x-www-form-urlencoded, multipart/form-data, or text/plain.
2. Preflight Requests (OPTIONS)
If a request uses methods like PUT or DELETE, custom headers (e.g., Authorization), or sends application/json data, the browser sends an automatic OPTIONS request first. This is called a preflight request.
The browser asks the server: "Are you willing to accept a POST request containing JSON from this origin?" The server must respond with a 204 No Content status and specify allowed origins, methods, and headers.
🛠️ Secure CORS Header Configuration
To resolve CORS errors, the server must attach specific HTTP headers to its responses.
| Header Name | Recommended Value | Security Risk |
|---|---|---|
Access-Control-Allow-Origin |
https://trusted-frontend.com |
HIGH: Never use * (wildcard) if your API processes sensitive data or requires user authentication. |
Access-Control-Allow-Methods |
GET, POST, OPTIONS |
Limit this strictly to the methods your client application uses. |
Access-Control-Allow-Headers |
Content-Type, Authorization |
Specify custom headers allowed in preflight requests. |
Access-Control-Allow-Credentials |
true |
Allows cookies and HTTP auth. If set to true, origin cannot be *. |
💻 Server Configurations (Python & Node.js)
Here is how to configure secure CORS controls on backend servers:
Node.js (Express Middleware)
```javascript const express = require('express'); const cors = require('cors'); const app = express();
const corsOptions = { origin: 'https://app.domain.com', methods: ['GET', 'POST', 'PUT', 'DELETE'], allowedHeaders: ['Content-Type', 'Authorization'], credentials: true };
app.use(cors(corsOptions)); ```
Python (Flask)
```python from flask import Flask from flask_cors import CORS
app = Flask(name)
Restrict CORS requests strictly to target origin
CORS(app, resources={r"/api/*": {"origins": "https://app.domain.com"}}) ```
Join the Urbandigistore Hub
Subscribe to receive premium developer cheat sheets, advanced conversion techniques, and campaign optimization checklists. Zero spam, unsubscribe anytime.