Node.js CORS
CORS stands for Cross-Origin Resource Sharing. It is a browser safety rule that controls which websites may call your API. Many beginners meet CORS through a red error message in the browser console. This lesson explains the rule and shows how to configure it.
What Is an Origin
An origin is the combination of protocol, website name, and port.
https://shop.com:443 | | | protocol host port
A change in any part creates a different origin. These addresses are all different origins.
- https://shop.com and http://shop.com differ by protocol.
- https://shop.com and https://api.shop.com differ by host.
- http://localhost:3000 and http://localhost:5000 differ by port.
The Rule Behind CORS
Browsers use the same-origin policy. A page from one origin cannot read data from another origin unless the other server gives permission. Think of an apartment building. A visitor from outside needs the owner to put a name on the guest list.
Page at http://localhost:3000
|
| asks for data from http://localhost:5000/api
v
+-----------------+ Guest list says: allow 3000?
| API server | ---------------------------------+
| port 5000 | |
+-----------------+ v
Yes: browser delivers data No: browser blocks it
The server still receives the request. The browser decides whether your page may read the answer.
The Typical Error
Access to fetch at 'http://localhost:5000/api'
from origin 'http://localhost:3000' has been blocked by CORS policy.The fix lives on the server. Frontend code cannot repair it.
Enable CORS in Express
npm install cors
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());The default setting allows every origin. This option suits public APIs and local testing.
Allow One Origin
Real projects name the trusted sites.
app.use(cors({
origin: "https://myshop.com"
}));Allow a List of Origins
const allowed = ["https://myshop.com", "https://admin.myshop.com"];
app.use(cors({
origin: (origin, callback) => {
if (!origin || allowed.includes(origin)) {
callback(null, true);
} else {
callback(new Error("Origin not allowed"));
}
}
}));More Settings
app.use(cors({
origin: "https://myshop.com",
methods: ["GET", "POST", "PUT", "DELETE"],
allowedHeaders: ["Content-Type", "Authorization"],
credentials: true,
maxAge: 600
}));- methods lists permitted request types.
- allowedHeaders lists permitted extra headers.
- credentials allows cookies and login details to travel.
- maxAge tells the browser to remember the answer for 600 seconds.
The setting credentials: true needs a specific origin. A wildcard star does not work with it.
Preflight Requests
Some requests need a permission check first. The browser sends a small OPTIONS request called a preflight. The server replies with the rules. The browser sends the real request after approval.
Browser Server |---- OPTIONS /api/items ------>| May I send a DELETE? |<--- Allow: DELETE, GET --------| Yes, you may. |---- DELETE /api/items/5 ----->| Real request |<--- 200 OK -------------------|
The cors package handles preflight requests automatically.
Apply CORS to One Route
app.get("/public-data", cors(), (req, res) => {
res.json({ open: true });
});Set Headers by Hand
The package sets response headers for you. You can also write them yourself.
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "https://myshop.com");
res.header("Access-Control-Allow-Methods", "GET,POST");
next();
});Safety Notes
- CORS protects browser users. It does not replace login checks.
- Tools such as curl and Postman ignore CORS entirely.
- Avoid wildcard access on APIs that serve private data.
- Keep the trusted origin list short and current.
Practice Tasks
- Run an API on port 5000 and a page on port 3000, trigger the error, and fix it with the cors package.
- Restrict the API to one origin and confirm another origin fails.
- Limit allowed methods to GET and POST.
