Step-by-step solutions for Cross-Origin Resource Sharing problems — server configs for Express, Next.js, Apache, Nginx
The server's response does not include the CORS header that authorizes your origin. The browser blocks the response.
Access-Control-Allow-Origin header to the response. See server examples below.The browser sent an OPTIONS preflight request (because your request has custom headers or non-simple method). The server responded with non-200 status or missing CORS headers for OPTIONS.
// Express example — before your route handler
app.options('/api/data', cors()); // preflight responderAuthorization, X-), or Content-Type other than application/x-www-form-urlencoded, multipart/form-data, text/plain.Your frontend sets withCredentials: true or credentials: 'include' (cookies, auth headers), but the server did not include Access-Control-Allow-Credentials: true in its response.
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin cannot be *. You must echo the specific origin:Access-Control-Allow-Origin: https://myapp.comAccess-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true. It's invalid and will be rejected by browsers.Your request includes a header that the server hasn't explicitly allowed in its Access-Control-Allow-Headers response header.
Access-Control-Allow-Headers:Access-Control-Allow-Headers: Authorization, X-Custom-Header, Content-TypeAuthorization, X-Requested-With, X-CSRF-Token. Access-Control-Allow-Headers: * is valid in Fetch spec but not universally supported; list explicitly for compatibility.Your request uses a method not listed in the server's Access-Control-Allow-Methods header in the preflight response.
Access-Control-Allow-Methods:Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, PATCHOPTIONS must be allowed because the browser sends an OPTIONS preflight request before the actual method.You want to allow several specific origins (not *). Echo back the Origin request header if it's in your whitelist.
// Express.js
const allowed = ["https://myapp.com", "https://admin.myapp.com"];
app.use(cors({
origin: (origin, callback) => {
if (!origin || allowed.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
}));// Next.js — middleware.js
export function middleware(request) {
const response = NextResponse.next();
const origin = request.headers.get('origin');
const allowed = ["https://myapp.com", "https://app.myapp.com"];
if (allowed.includes(origin)) {
response.headers.set('Access-Control-Allow-Origin', origin);
response.headers.set('Access-Control-Allow-Credentials', 'true');
}
return response;
}!origin check allows same-origin requests (mobile apps, Postman) that send no Origin header.# .htaccess in document root
<IfModule mod_headers.c>
Header always set Access-Control-Allow-Origin "https://myapp.com"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Authorization, Content-Type"
Header always set Access-Control-Allow-Credentials "true"
</IfModule># Handle OPTIONS preflight
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]mod_headers enabled (a2enmod headers). For dynamic origin, need mod_setenvif or server-side scripting (PHP/Python).# nginx.conf or site config
location /api/ {
add_header 'Access-Control-Allow-Origin' 'https://myapp.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
# Preflight
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
}always ensures headers are set even on error responses. Access-Control-Max-Age (seconds) caches preflight in browser. 1728000 = 20 days.export default {
async fetch(request, env, ctx) {
const response = await fetch(request);
const newHeaders = new Headers(response.headers);
newHeaders.set('Access-Control-Allow-Origin', 'https://myapp.com');
newHeaders.set('Access-Control-Allow-Credentials', 'true');
return new Response(response.body, {
status: response.status,
headers: newHeaders
});
}
};Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Credentials: truehttp://localhost:3000, http://127.0.0.1:5173, etc.Access-Control-Allow-Origin: http://localhost:3000
https://myapp.comCORS validation is per-response. A redirect response must itself have the appropriate Access-Control-Allow-Origin header if it's cross-origin, but usually redirects don't include CORS headers.
Access-Control-Allow-Origin (rarely practical).As we navigate the interconnected web of 2026, Cross-Origin Resource Sharing (CORS) remains one of the most common→and often frustrating→security hurdles for developers. Designed to protect users from malicious scripts, CORS is a mechanism that uses additional HTTP headers to tell browsers whether a web application running at one origin has permission to access selected resources from a different origin. Whether you're building a modern microservices architecture or simply trying to fetch data from a third-party API, understanding the nuances of "Preflight Requests," "Allow-Origins," and "Credentials" is essential for professional web development.
A major focus in 2026 is the security of "Credentials" in cross-origin requests. Many developers fall into the trap of using Access-Control-Allow-Origin: * while also trying to send cookies or Authorization headers. As per modern security standards, this combination is strictly prohibited by browsers. Our guide provides specific, framework-ready solutions for dynamically echoing the correct origin, ensuring your application remains both secure and functional. By prioritizing specific origin whitelisting over wildcards, you protect your users and your infrastructure from potential cross-site request forgery (CSRF) and other common web vulnerabilities.
Finally, consider the role of "Edge Configuration" in managing CORS. In the 2026 digital landscape, many CORS issues can be resolved at the CDN or edge level (like Cloudflare Workers or AWS CloudFront Functions) before they even reach your application server. This not only improves performance by reducing "CORS latency" but also provides a centralized location for managing your security policies. By combining these edge strategies with the "Local-First" diagnostic utilities of AllOmnitools, you can quickly identify, test, and resolve CORS errors in a secure, high-performance environment that respects your data privacy.
Zero server lag. All CORS fixes and server configurations are available instantly for your workflow.
Your API structures and server details remain private. We never track or store your security configurations.
A preflight request is an automatic OPTIONS request sent by the browser before the actual request. It checks with the server if the cross-origin call is safe and allowed based on the method and headers used.
Security standards prohibit using Access-Control-Allow-Origin: * when Access-Control-Allow-Credentials is set to true. This prevents sensitive data (like cookies) from being accessed by any arbitrary website.
The best way is to configure your local development server (like Vite or Webpack) to proxy requests to your API. This makes the request appear as same-origin to the browser, bypassing CORS checks entirely.
Yes. At AllOmnitools, we prioritize your privacy. We provide the information and code snippets locally in your browser. You never need to submit your proprietary API details to our servers.
No. CORS is a browser-level security feature. It doesn't prevent tools like Postman or curl from making requests. Always implement proper server-side authentication and rate limiting for complete security.
If you don't control the server, you can't "fix" CORS directly. Your options are to use a proxy server that you *do* control or ask the API provider to add your origin to their whitelist.