Introduction
Cross‑Origin Resource Sharing (CORS) errors are a common roadblock when building fast, scalable APIs with Node.js. This guide walks you through the root causes of CORS failures and provides a step‑by‑step solution that works with both Express and Fastify, the two most popular Node.js frameworks.
Why CORS Errors Appear in High‑Performance Node.js Apps
- Browser security model – browsers block requests to a different origin unless the server explicitly allows it.
-
Pre‑flight requests – for methods like
PUT,DELETEor custom headers, browsers send anOPTIONSrequest first. -
Missing or mis‑configured headers –
Access‑Control-Allow-Origin,Access‑Control-Allow-Methods,Access‑Control-Allow-Headers. - Fast response times – when your API responds in milliseconds, a missing header can be overlooked during rapid development.
Prerequisites
- Node.js >= 14
- npm or yarn
- A basic Fastify (or Express) project
Step‑by‑Step Fix for Fastify
- Install the CORS plugin
npm install fastify-cors
- Register the plugin with sensible defaults
const fastify = require('fastify')();
// Register fastify‑cors
fastify.register(require('fastify-cors'), {
origin: '*', // change to specific domains in production
methods: ['GET','POST','PUT','DELETE','OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
});
// Example route
fastify.get('/api/hello', async (request, reply) => {
return {msg: 'Hello from Fastify with CORS enabled'};
});
fastify.listen(3000, err => {
if (err) process.exit(1);
console.log('🚀 Server listening on http://localhost:3000');
});
-
Verify the
OPTIONSpre‑flight – Fastify automatically handlesOPTIONSwhen the plugin is registered. You can test it withcurl:
curl -i -X OPTIONS http://localhost:3000/api/hello \
-H "Origin: http://example.com" \
-H "Access-Control-Request-Method: GET"
You should see Access-Control-Allow-Origin: * in the response headers.
Express Alternative (if you prefer Express)
npm install cors
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: '*',
methods: ['GET','POST','PUT','DELETE','OPTIONS'],
allowedHeaders: ['Content-Type','Authorization'],
credentials: true,
}));
app.get('/api/hello', (req, res) => {
res.json({msg: 'Hello from Express with CORS enabled'});
});
app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Advanced Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
No 'Access-Control-Allow-Origin' header |
Header not set for the route | Ensure the CORS middleware is registered before route definitions. |
CORS pre‑flight request fails (405) |
OPTIONS not handled |
Fastify‑cors/Express‑cors automatically adds an OPTIONS handler; double‑check plugin registration. |
Credentials blocked |
Access-Control-Allow-Credentials missing while origin is *
|
Set origin to an explicit whitelist and enable credentials: true. |
Invalid header name |
Custom header not listed in allowedHeaders
|
Add the header name to allowedHeaders array. |
Tip: Use the browser’s dev tools → Network tab to inspect the request and response headers for the failing call.
Automating the Fix
If you need to apply the same configuration across many services, the following script can inject the CORS setup into existing Fastify projects:
// inject-cors.js – run with `node inject-cors.js <project‑path>`
const fs = require('fs');
const path = require('path');
const target = process.argv[2];
if (!target) { console.error('Provide project path'); process.exit(1); }
const entry = path.join(target, 'index.js');
let code = fs.readFileSync(entry, 'utf8');
if (!code.includes('fastify-cors')) {
const snippet = `fastify.register(require('fastify-cors'), {origin: '*', methods: ['GET','POST','PUT','DELETE','OPTIONS'], allowedHeaders: ['Content-Type','Authorization'], credentials: true});\n`;
code = code.replace(/(const\s+fastify\s*=\s*require\(['"]fastify['"]\)\(\);)/, `$1\n${snippet}`);
fs.writeFileSync(entry, code);
console.log('CORS middleware injected successfully.');
} else {
console.log('CORS already configured.');
}
You can Download the pre‑configured script here, or Get the complete patch tool for bulk updates. For the full repository with tests and CI configuration, Access the full repository fix.
Conclusion
CORS errors disappear when you:
- Install a reliable middleware (
fastify-corsorcors). - Register it before any route handlers.
- Configure origins, methods, and headers according to your security policy.
- Verify with browser dev tools or
curl.
Apply the script above to standardize the fix across multiple services and keep your APIs fast and secure.
Top comments (0)