Real-world examples of CORS in Node.js API: 3 practical setups that actually work
Most CORS explainers start with dry definitions. Let’s skip that and jump straight into examples of CORS in a Node.js API that you’d actually run in 2024–2025.
We’ll build around a simple Express server, then layer in different CORS configurations:
npm init -y
npm install express cors
// server.js
const express = require('express');
const cors = require('cors');
const app = express();
app.use(express.json());
app.get('/public', (req, res) => {
res.json({ message: 'Public data' });
});
app.listen(4000, () => {
console.log('API running on http://localhost:4000');
});
Now let’s walk through three practical examples of CORS in a Node.js API, plus a few extra scenarios you’ll hit in real projects.
Example 1: Wide-open CORS for public APIs and local development
This is the “just make it work” setup. You’ll see it in tutorials, internal tools, and dev environments. It allows any origin and most basic methods.
// Example 1: Allow all origins (development or public demo)
const cors = require('cors');
app.use(cors());
// Optional: be explicit
// app.use(cors({ origin: '*', methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'] }));
In this first example of CORS in a Node.js API, the cors() middleware with no options tells browsers:
- Any website can call this API.
- Simple requests (GET, basic POST) just work.
- Preflight requests (
OPTIONS) get an automatic OK.
When this “open” CORS example makes sense
Real examples where this pattern is fine:
- A public, read-only API with no user data (e.g., a demo weather or crypto price feed).
- Internal dashboards behind VPN or SSO where network controls are already strict.
- Local development where your React/Vue front end runs on
http://localhost:3000and your Node.js API runs onhttp://localhost:4000.
From an SEO perspective, many developers search for “best examples of CORS in Node.js API: 3 practical examples” and land here first. But in production, this wide-open pattern is rarely what you want.
Hidden gotcha: cookies and Authorization headers won’t work
If you later try to send cookies or Authorization: Bearer ... headers from the browser, this open example suddenly stops working for authenticated flows. You’ll need a more specific configuration, which brings us to the second pattern.
Example 2: Locked-down CORS for a single front-end origin
Most real apps in 2024–2025 have a single primary front end hitting a single API: think React SPA + Node.js backend. In that case, the best examples of CORS configurations are the ones that:
- Allow only a known origin (your front-end URL).
- Allow credentials (cookies, Authorization headers).
- Restrict methods and headers to what you actually use.
Here’s a tighter, production-style example of CORS in a Node.js API:
const cors = require('cors');
const allowedOrigin = process.env.FRONTEND_ORIGIN || 'https://app.example.com';
app.use(cors({
origin: allowedOrigin,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
}));
// Browsers send OPTIONS preflight for some requests
app.options('*', cors({
origin: allowedOrigin,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
}));
This is one of the most common real examples of CORS in Node.js API setups in production apps.
Why this pattern actually works in 2024–2025
Modern SPAs often rely on:
- JWT in Authorization headers for auth.
- SameSite=None; Secure cookies for session-based auth.
- Custom headers like
X-Request-IdorX-Client-Version.
Browsers treat those as non-simple requests, so they send a preflight OPTIONS request. If your CORS config doesn’t match the actual method and headers, the browser quietly blocks the call.
By explicitly listing allowedHeaders and methods, this example keeps your CORS behavior predictable and easier to debug.
Common mistakes with this CORS example
Even experienced teams trip over a few recurring issues:
- Setting
origin: '*'while also usingcredentials: true– browsers will reject this. - Forgetting to handle
OPTIONSrequests, which makes preflight fail. - Allowing
Authorizationbut forgetting a custom header likeX-Requested-With, causing random failures.
For a deeper look at CORS behavior from the browser’s perspective, the MDN docs are still the gold standard: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Example 3: Per-route CORS for multi-tenant and microservice setups
Sometimes your API isn’t just one thing. Maybe you have:
- A public
/publicendpoint for marketing pages. - A locked-down
/apifor your main web app. - A partner-only
/partnerroute for B2B integrations.
In that case, global CORS middleware is too blunt. You want route-level CORS rules. Here’s a more advanced example of CORS in a Node.js API using per-route configuration:
const cors = require('cors');
const publicCors = cors({ origin: '*' });
const appCors = cors({
origin: 'https://app.example.com',
methods: ['GET', 'POST'],
credentials: true,
});
const partnerCors = cors({
origin: [/\.partner1\.com\(/, /\.partner2\.com\)/],
methods: ['GET', 'POST', 'PUT'],
allowedHeaders: ['Content-Type', 'Authorization', 'X-Partner-Key'],
});
// Public route: any origin can read
app.get('/public', publicCors, (req, res) => {
res.json({ message: 'Public data' });
});
// Main app API: only your SPA
app.get('/api/profile', appCors, (req, res) => {
res.json({ user: 'Jane Doe' });
});
// Partner API: only specific partner subdomains
app.post('/partner/orders', partnerCors, (req, res) => {
res.status(201).json({ status: 'created' });
});
This is one of the best examples of CORS in Node.js API design when you have multiple clients with different trust levels. It mirrors how many SaaS platforms structure their APIs today.
Extra real-world scenarios: 4 more examples of CORS patterns you’ll actually use
The title promised 3 practical setups, but real life is messier than that. Here are four additional real examples of CORS in Node.js API configurations that show up in modern stacks.
Example 4: Dynamic CORS origin checking at runtime
Sometimes you can’t hard-code all allowed origins. Think multi-tenant SaaS where each customer gets a custom domain.
const cors = require('cors');
const allowedOrigins = new Set([
'https://app.example.com',
'https://admin.example.com',
]);
const corsOptionsDelegate = (req, callback) => {
const origin = req.header('Origin');
let corsOptions;
if (origin && allowedOrigins.has(origin)) {
corsOptions = { origin: true, credentials: true };
} else {
corsOptions = { origin: false };
}
callback(null, corsOptions);
};
app.use(cors(corsOptionsDelegate));
This example of dynamic CORS in a Node.js API lets you:
- Read allowed origins from a database or config service.
- Toggle access without redeploying the API.
- Log or alert when unknown origins attempt access.
Example 5: CORS with cookies for legacy session-based auth
Not every app has moved to pure JWT. If you’re using session cookies, your CORS config needs to match modern browser rules (especially Chrome’s SameSite changes).
const cors = require('cors');
const session = require('express-session');
app.use(cors({
origin: 'https://app.example.com',
credentials: true,
}));
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: true,
sameSite: 'none',
},
}));
This is a very common example of CORS in Node.js API setups for organizations modernizing older apps: front end is new, backend still uses sessions.
If you’re handling authentication and sensitive data, it’s worth reviewing federal guidance on secure web sessions, such as NIST’s recommendations around cookies and session management: https://csrc.nist.gov
Example 6: CORS behind an API gateway or reverse proxy
In larger deployments, CORS might be handled partly by NGINX, an API gateway, or a cloud load balancer. Your Node.js API still needs to play nicely.
A realistic pattern in 2024–2025:
- Gateway adds
Access-Control-Allow-Originfor public endpoints. - Node.js adds CORS headers only for internal or special routes.
// Only add CORS for internal tools; public CORS handled by gateway
app.use('/internal', cors({
origin: 'https://internal-tools.example.com',
methods: ['GET', 'POST'],
}));
If you’re in a regulated industry (healthcare, finance, government), you’ll often see CORS policies documented alongside security controls. For example, U.S. government web security guidance emphasizes origin and header restrictions as part of a defense-in-depth model: https://www.cisa.gov
Example 7: CORS in local dev with multiple front ends
Modern teams often run multiple local front ends: admin UI, main app, documentation site. Here’s a simple but realistic example:
const cors = require('cors');
const devOrigins = [
'http://localhost:3000', // main app
'http://localhost:3001', // admin
'http://localhost:3002', // docs
];
app.use(cors({
origin: devOrigins,
credentials: true,
}));
This kind of configuration is one of the best examples of CORS in Node.js API setups that keep development flexible without accidentally allowing the whole internet.
Debugging CORS: why your “perfect” example still fails
Even with good examples of CORS in a Node.js API, things go wrong. A few practical debugging habits:
- Check the browser’s network tab: look at the
OPTIONSpreflight response. - Verify headers: your API must send
Access-Control-Allow-Origin,Access-Control-Allow-Methods, andAccess-Control-Allow-Headersthat match what the browser asked for. - Log the Origin header: during development, log
req.headers.originto see who’s calling you.
If you’re working in health or medical contexts where cross-origin data access raises privacy questions, organizations like the U.S. National Institutes of Health publish guidance on protecting personal health information in web apps: https://www.nih.gov
FAQ: common questions about CORS in Node.js APIs
What are some real examples of CORS configurations in Node.js?
Real examples of CORS in Node.js API setups include:
- Allow-all for public or demo APIs.
- Single-origin with credentials for SPAs.
- Per-route CORS for public vs. private endpoints.
- Dynamic origin checking for multi-tenant apps.
- Cookie-based session APIs with
SameSite=Noneandcredentials: true.
All of these examples of CORS patterns appear in production systems today.
Can you show an example of allowing only GET and POST with CORS?
Yes. Here’s a compact example of CORS in a Node.js API that only allows GET and POST from a specific origin:
app.use(cors({
origin: 'https://app.example.com',
methods: ['GET', 'POST'],
}));
Browsers will block PUT, PATCH, or DELETE requests from other origins in this setup.
Do I always need the cors package for Node.js?
No. You can manually set CORS headers with plain Express:
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://app.example.com');
res.header('Access-Control-Allow-Methods', 'GET,POST');
res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');
if (req.method === 'OPTIONS') {
return res.sendStatus(204);
}
next();
});
But for most developers, the cors middleware is easier to reason about and less error-prone.
How do I test these examples of CORS in Node.js API locally?
Run your Node.js API on one port (say 4000) and a simple front end (even a static HTML file served by live-server or Vite) on another port (3000). Open the browser console, make fetch calls, and watch for CORS errors. Adjust the origin and methods in your examples of CORS config until the browser stops complaining.
If you remember nothing else, remember this: the best examples of CORS in Node.js API design are the ones that mirror your actual clients—their origins, methods, headers, and auth style. Start with one of the practical examples above, tighten it to match your reality, and your CORS errors will finally stop hijacking your debugging sessions.
Related Topics
Best examples of adding middleware in a Node.js API – Practical Examples for 2025
Real-world examples of 3 examples of setting up a Node.js server
3 Best Examples of Deploying a Node.js API to Heroku
Real-world examples of CORS in Node.js API: 3 practical setups that actually work
Explore More Building a Simple API with Node.js
Discover more examples and insights in this category.
View All Building a Simple API with Node.js