The CORS Error You've Seen
This error means: your JavaScript on app.mysite.com tried to read a response from api.example.com, but the server did not return headers giving permission. The browser blocked it.
What is the Same-Origin Policy?
Browsers enforce the Same-Origin Policy: JavaScript on one origin cannot read responses from a different origin. An origin is defined as: scheme + hostname + port.
| URL | Same origin as https://example.com? | Reason |
|---|---|---|
| https://example.com/page | Yes | Same scheme, host, port |
| http://example.com | No | Different scheme (http vs https) |
| https://api.example.com | No | Different subdomain |
| https://example.com:8080 | No | Different port |
| https://other.com | No | Different host |
How CORS Works
CORS lets servers relax the same-origin policy selectively. The server adds response headers to say which origins are allowed:
When the browser sees Access-Control-Allow-Origin matching the current origin, it allows JavaScript to read the response.
Simple vs Preflight Requests
Simple requests (no preflight)
Requests meeting ALL of these conditions skip preflight:
- Method is GET, POST, or HEAD
- Content-Type is
text/plain,multipart/form-data, orapplication/x-www-form-urlencoded - No custom headers (no Authorization, no custom X-headers)
Complex requests (preflight required)
Anything else triggers an automatic OPTIONS preflight first:
How to Fix CORS — By Framework
Node.js / Express
Nginx
PHP
⚠️ Never Use * With Credentials
If your request includes cookies or an Authorization header (credentials: 'include' in fetch), you cannot use Access-Control-Allow-Origin: *. You must specify the exact origin AND add Access-Control-Allow-Credentials: true.
💡 CORS is a Browser Feature, Not a Server Feature
CORS errors only appear in browsers. Server-to-server requests, Postman, and curl are never blocked by CORS — only browser JavaScript is. If your API needs to prevent unauthorised server-to-server access, use API keys or OAuth, not CORS.
How We Research and Update This Guide
We test the underlying formula or workflow, compare outputs with reliable references, and revise examples whenever the page content changes.
- The workflow or formula is tested directly in the tool and compared against independent reference examples.
- Examples are kept practical so readers can verify the result without hidden assumptions.
- Pages are revised whenever the interface, calculation flow, or surrounding guidance materially changes.
Frequently Asked Questions — CORS
CORS exists because of the Same-Origin Policy (SOP) — a browser security rule that prevents JavaScript on one origin (e.g. evil.com) from making requests to another origin (e.g. yourbank.com) and reading the response. Without this, a malicious site could make authenticated requests to your bank using your stored cookies. CORS is the mechanism that lets servers selectively relax this restriction for trusted origins.
CORS is enforced by the browser — it is a browser security feature, not a server security feature. Postman, curl, and server-to-server requests are not subject to CORS. The browser adds the Origin header and checks the server's CORS response headers before allowing JavaScript to read the response. If the server does not return the correct headers, the browser blocks access — but the request still reached the server.
A preflight is an automatic OPTIONS request the browser sends before certain "complex" requests (those with custom headers, non-GET/POST methods, or content types other than text/plain, multipart/form-data, application/x-www-form-urlencoded). The browser asks the server: "Will you allow a PUT request from origin X with Authorization header?" The server responds with CORS headers. If approved, the browser sends the actual request.
Simple requests (GET/POST/HEAD with only basic headers and standard content types) do not trigger a preflight — the browser sends them directly. Complex requests (PUT/DELETE/PATCH, custom headers like Authorization, or content type application/json) trigger a preflight OPTIONS request first. Most API calls are complex because they use Authorization headers or JSON bodies.
The wildcard * allows any origin to read the response. This is appropriate for fully public APIs with no authentication. However, you cannot use * when the request includes credentials (cookies or Authorization headers) — in that case, you must specify the exact origin (e.g. Access-Control-Allow-Origin: https://yourapp.com) and also set Access-Control-Allow-Credentials: true.
No. CORS and CSRF protection are different things. CORS controls whether cross-origin JavaScript can READ the response. CSRF is about preventing cross-origin requests from being MADE using the user's cookies. A form submission from evil.com to yourbank.com will succeed even with CORS configured correctly, because form submissions do not use JavaScript to read the response. Use CSRF tokens or SameSite cookies for CSRF protection.