TL;DR
CORS blocks cross-origin requests by default - that's a security feature, not a bug. The fix isn't "allow all origins" - it's explicitly allowing YOUR frontend origins. Never use Access-Control-Allow-Origin: * with credentials. These prompts help you configure CORS correctly.
Understand CORS Errors
Help me understand and fix this CORS error.
Error: paste your CORS error here
Common CORS errors and meanings:
- "No 'Access-Control-Allow-Origin' header" Your server isn't sending CORS headers at all. Fix: Add CORS middleware/headers to your API.
- "Origin 'X' is not allowed" Server has CORS but your origin isn't in the list. Fix: Add your frontend's origin to allowed origins.
- "Preflight response is not successful" OPTIONS request failing. Fix: Ensure server handles OPTIONS and returns proper headers.
- "Credentials not supported with wildcard origin" Using * with credentials: 'include'. Fix: Specify exact origin, not *.
- "Request header field X is not allowed" Custom header not in Access-Control-Allow-Headers. Fix: Add your custom headers to allowed headers list.
Tell me:
- What origin is making the request?
- What origin is the API on?
- Are you using credentials (cookies/auth)?
- What HTTP method and headers?
Express CORS Configuration
Set up secure CORS configuration in my Express API.
npm install cors
const cors = require('cors');
// SECURE: Explicit origin list const allowedOrigins = 'https://myapp.com', 'https://www.myapp.com', process.env.NODE_ENV === 'development' && 'http://localhost:3000' .filter(Boolean);
app.use(cors({ origin: (origin, callback) => { // Allow requests with no origin (mobile apps, Postman) if (!origin) return callback(null, true);
if (allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('CORS not allowed'));
}
}, credentials: true, // Allow cookies methods: 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', allowedHeaders: 'Content-Type', 'Authorization', maxAge: 86400 // Cache preflight for 24 hours }));
// INSECURE - Never do this: // app.use(cors({ origin: '*', credentials: true })); // Won't work AND is dangerous
Put CORS middleware BEFORE your routes.
Never use Access-Control-Allow-Origin: * with credentials: It doesn't even work (browsers reject it), and attempting it signals you don't understand CORS. Always specify exact origins when using cookies or auth headers.
Next.js API Routes CORS
Add CORS to my Next.js API routes.
For Next.js 13+ App Router, create middleware.ts:
import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server';
const allowedOrigins = 'https://myapp.com', process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : null .filter(Boolean);
export function middleware(request: NextRequest) { const origin = request.headers.get('origin'); const response = NextResponse.next();
if (origin && allowedOrigins.includes(origin)) { response.headers.set('Access-Control-Allow-Origin', origin); response.headers.set('Access-Control-Allow-Credentials', 'true'); response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization'); }
// Handle preflight if (request.method === 'OPTIONS') { return new NextResponse(null, { status: 200, headers: response.headers }); }
return response; }
export const config = { matcher: '/api/:path*', };
Preflight Requests
Fix preflight request issues in my API.
Browsers send OPTIONS preflight for:
- Non-simple methods (PUT, DELETE, PATCH)
- Custom headers (Authorization, X-Custom-Header)
- Content-Type other than form-data, text/plain, application/x-www-form-urlencoded
Your server must:
- Respond to OPTIONS with 200/204
- Include all CORS headers
- Not require authentication for OPTIONS
Express example: app.options('*', cors()); // Handle all preflight
// Or manually: app.options('/api/*', (req, res) => { res.header('Access-Control-Allow-Origin', req.headers.origin); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.header('Access-Control-Max-Age', '86400'); res.sendStatus(204); });
Cache preflight with Max-Age to reduce OPTIONS requests. Never put authentication middleware before CORS/OPTIONS handling.
Pro tip: If your frontend and API are on the same origin, you don't need CORS at all. Consider proxying API requests through your frontend server (Next.js rewrites, nginx proxy_pass) to avoid CORS entirely.
My API works in Postman but not the browser. Why?
Postman doesn't enforce CORS - only browsers do. CORS is a browser security feature. Your API needs to send CORS headers for browser requests from different origins.
Can I just disable CORS in the browser?
You can for development with browser flags, but you can't do it for your users. Fix CORS on the server - that's the only real solution. Browser workarounds are development-only.