How to fix Error: Access to XMLHttpRequest blocked by CORS policy (cross-origin request) in Node.js
This error occurs when a web application tries to make a cross-origin HTTP request, but the server does not allow requests from the requesting origin. Browsers enforce CORS (Cross-Origin Resource Sharing) to protect users from potentially malicious cross-origin requests.
Quick fix
Fixes Error: Access to XMLHttpRequest blocked by CORS policy (cross-origin request)
npm install cors- Install the cors middleware package
- Enable CORS for all routes (development)
- Configure CORS for specific origins (production)
- Handle preflight OPTIONS requests
npm install corsError: Access to XMLHttpRequest blocked by CORS policy (cross-origin request)
npm install corsWhat this error means
This error indicates that your web application is attempting to make an HTTP request from one origin (domain, protocol, or port) to a different origin, and the browser has blocked it due to the Same-Origin Policy. For example, if your frontend runs on http://localhost:3000 and tries to fetch data from http://localhost:5000, the browser will block this unless the backend server explicitly allows it. CORS is a security mechanism that requires servers to send specific HTTP headers (like Access-Control-Allow-Origin) to inform the browser which origins are permitted to access resources. Without these headers, browsers will refuse to expose the response to the requesting script, resulting in this error. The error commonly appears when developing full-stack applications where the frontend and backend run on different ports during development, or when a production app makes API calls to a different domain.
Typical symptoms
- Network requests fail in the browser console with CORS policy errors
- Frontend cannot fetch data from the backend API despite the server responding
- Console shows "No Access-Control-Allow-Origin header is present" message
- OPTIONS preflight requests return without proper CORS headers
- Requests work in Postman or curl but fail in the browser
- Custom headers or non-simple HTTP methods (PUT, DELETE, PATCH) are blocked
Common causes
- Backend server does not have CORS configured or enabled
- Server Access-Control-Allow-Origin header does not include the requesting origin
- Missing or incorrect CORS middleware configuration in Express or Node.js
- Server does not handle preflight OPTIONS requests properly
- Wildcard origin (*) used with credentials mode, which browsers reject
- CORS headers configured but not applied to all routes or HTTP methods
- Server running on different protocol (HTTP vs HTTPS) than frontend
- Environment-specific CORS configuration not updated for production domains
How to fix "Error: Access to XMLHttpRequest blocked by CORS policy (cross-origin request)"
The cors npm package provides Express middleware that automatically handles CORS headers and preflight requests.
npm install corsOr with yarn:
yarn add corsFor quick development testing, enable CORS for all origins and routes. Import cors and add it as middleware before your routes:
const express = require('express');
const cors = require('cors');
const app = express();
// Enable CORS for all routes and origins
app.use(cors());
app.get('/api/data', (req, res) => {
res.json({ message: 'CORS is enabled' });
});
app.listen(5000, () => {
console.log('Server running on port 5000');
});This allows requests from any origin. Note: This is suitable for development but not recommended for production.
For production, restrict CORS to specific trusted origins. Configure the cors middleware with an origin whitelist:
const express = require('express');
const cors = require('cors');
const app = express();
const corsOptions = {
origin: ['https://yourdomain.com', 'https://app.yourdomain.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true, // Allow cookies and credentials
optionsSuccessStatus: 200 // Some legacy browsers choke on 204
};
app.use(cors(corsOptions));
app.get('/api/data', (req, res) => {
res.json({ message: 'CORS configured for specific origins' });
});
app.listen(5000);For dynamic origin validation based on environment:
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000'];
const corsOptions = {
origin: function (origin, callback) {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
};
app.use(cors(corsOptions));Complex requests (using methods like PUT, DELETE, or custom headers) trigger a preflight OPTIONS request. Ensure your server handles these:
const express = require('express');
const cors = require('cors');
const app = express();
// Enable pre-flight across all routes
app.options('*', cors());
// Apply CORS middleware
app.use(cors());
app.delete('/api/resource/:id', (req, res) => {
// This route now properly handles preflight
res.json({ message: 'Resource deleted' });
});
app.listen(5000);If implementing CORS manually without the package:
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://yourdomain.com');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Access-Control-Allow-Credentials', 'true');
// Handle preflight
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});After configuring CORS, verify the headers are being sent correctly:
1. Open browser DevTools (F12)
2. Go to the Network tab
3. Make the cross-origin request
4. Click on the request to inspect headers
5. Check the Response Headers section for:
- Access-Control-Allow-Origin: <your-origin>
- Access-Control-Allow-Methods: ...
- Access-Control-Allow-Headers: ...
For preflight requests, look for an OPTIONS request that precedes your actual request. It should return a 200 or 204 status with proper CORS headers.
If headers are missing, ensure the cors middleware is applied before your route handlers and that no other middleware is interfering.
Advanced notes
Security Considerations:
Never use origin: '*' (wildcard) with credentials: true in production. Browsers will reject this configuration. If you need to support credentials (cookies, authorization headers), you must specify exact origins.
Proxy Alternative for Development:
During development, you can bypass CORS by configuring a proxy in your frontend build tool instead of enabling CORS on the backend. For example, in package.json for Create React App:
{
"proxy": "http://localhost:5000"
}This makes the dev server proxy API requests to your backend, avoiding cross-origin issues entirely.
Performance Optimization:
Preflight requests add latency. You can cache preflight responses with the Access-Control-Max-Age header to reduce overhead:
const corsOptions = {
origin: 'https://yourdomain.com',
maxAge: 86400 // Cache preflight for 24 hours
};Multiple Origin Patterns:
Use regex patterns to allow multiple subdomains:
const corsOptions = {
origin: /\.yourdomain\.com$/,
credentials: true
};This allows app.yourdomain.com, api.yourdomain.com, etc., while blocking unrelated origins.
Frequently asked questions
- What does "Error: Access to XMLHttpRequest blocked by CORS policy (cross-origin r" mean?
- This error indicates that your web application is attempting to make an HTTP request from one origin (domain, protocol, or port) to a different origin, and the browser has blocked it due to the Same-Origin Policy. For example, if your frontend runs on http://localhost:3000 and tries to fetch data from http://localhost:5000, the browser will block this unless the backend server explicitly allows it. CORS is a security mechanism that requires servers to send specific HTTP headers (like Access-Control-Allow-Origin) to inform the browser which origins are permitted to access resources.
- How do I fix "Error: Access to XMLHttpRequest blocked by CORS policy (cross-origin r"?
- This error occurs when a web application tries to make a cross-origin HTTP request, but the server does not allow requests from the requesting origin. Browsers enforce CORS (Cross-Origin Resource Sharing) to protect users from potentially malicious cross-origin requests.
- What causes "Error: Access to XMLHttpRequest blocked by CORS policy (cross-origin r"?
- Backend server does not have CORS configured or enabled Server Access-Control-Allow-Origin header does not include the requesting origin Missing or incorrect CORS middleware configuration in Express or Node.js
- Is the "Error: Access to XMLHttpRequest blocked by CORS policy (cross-origin r" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐Node.js Official Documentation
- ๐MDN Cross-Origin Resource Sharing (CORS) documentation(Official Docs)
- ๐Express CORS middleware official documentation(Official Docs)
- ๐MDN CORS missing Allow-Origin header error reference(Official Docs)