Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

CORS

The browser protects visitors: a script on one site's page cannot simply read another site's response. A site is identified by its origin — the scheme, domain and port. CORS (Cross-Origin Resource Sharing) is a set of rules by which a server tells the browser which foreign origins may read its responses.

When you need it

Say the blog's React frontend runs at http://localhost:5173 and the API at http://localhost:3000. The ports differ, so the origins differ too. The frontend script makes a request:

// src/main.js (frontend)
const response = await fetch('http://localhost:3000/api/posts');
const posts = await response.json();
console.log(posts);

The server answers, but the browser does not hand the response to the script and logs an error with the words blocked by CORS policy in the console. A request from curl or from another server still works: only the browser checks CORS.

Installation

npm install cors

Allowing one origin

Add the middleware in src/app.js for the API addresses:

// src/app.js
import cors from 'cors';
 
app.use('/api', cors({ origin: 'http://localhost:5173' }));

The middleware adds the header Access-Control-Allow-Origin: http://localhost:5173 to responses. Reload the frontend page and the array of posts appears in the console.

Several origins

origin also accepts an array — for example, the development address and the production domain:

// src/app.js
app.use('/api', cors({
  origin: ['http://localhost:5173', 'https://example.com'],
  methods: ['GET', 'POST', 'PATCH', 'DELETE'],
}));

The browser still blocks requests from other sites.

The preflight request

Before "non-simple" requests — such as DELETE, or a POST with JSON and an Authorization header — the browser first sends a request with the OPTIONS method on its own. It asks the server whether such a request is allowed. The cors middleware answers it by itself when mounted with app.use(): no extra code is needed.

Response headerWhat it allows
Access-Control-Allow-OriginReading the response from the given origin
Access-Control-Allow-MethodsUsing the listed methods
Access-Control-Allow-HeadersSending the listed headers
Access-Control-Allow-CredentialsSending cookies

Cookies from another origin

If the frontend must send the session cookie, you need two things: the credentials: true option in cors() on the server and credentials: 'include' in fetch() on the client. With a JWT in the Authorization header this is not required.

Common mistake

Calling cors() without options allows requests from any site. For a public read-only API that is acceptable, but not for addresses that change data. Always list your origins in origin. And remember: CORS does not replace authentication — it restricts only browsers, and programs can reach the API directly.

Thanks for reading!

Donate to the site — we work hard for you.