What Is CORS? The Browser Security Rule, Explained
CORS (Cross-Origin Resource Sharing) is how browsers decide whether a web page can call an API at a different origin. Plain explanation of origins, preflights, and how to fix common CORS errors.
Short answer
CORS (Cross-Origin Resource Sharing) is a browser security rule that blocks JavaScript running on one website from reading responses from a different website — unless the target server explicitly opts in by sending an Access-Control-Allow-Origin header. It's the reason your frontend can't just call any API you want; the API has to allow you.
What "origin" means
An origin is the scheme + host + port triple: https://example.com:443. Two URLs share an origin only if all three match. https://example.com and https://api.example.com are different origins. So are http://example.com (port 80) and https://example.com (port 443). This granularity is why CORS trips up developers constantly.
The rule, simplified
- Same-origin request: no restrictions. Browser sends request, reads response.
- Cross-origin request: the browser still sends the request — but it won't let the JavaScript read the response unless the server includes the right CORS headers.
- Same-origin policy does NOT block the request — this is a common misunderstanding. Your POST still arrives at the server. Only the response reading is blocked client-side.
The key headers
| Header | Set by | Meaning |
|---|---|---|
Origin | Browser | Which origin is making the request |
Access-Control-Allow-Origin | Server response | Which origins may read the response (* = any) |
Access-Control-Allow-Methods | Server preflight response | Allowed HTTP verbs |
Access-Control-Allow-Headers | Server preflight response | Allowed custom request headers |
Access-Control-Allow-Credentials | Server response | Whether cookies may be sent cross-origin |
Access-Control-Max-Age | Server preflight response | How long to cache the preflight |
Preflight requests — the hidden OPTIONS
For "non-simple" requests (POST with JSON body, custom headers, PUT/DELETE, etc.), the browser first sends an OPTIONS "preflight" request asking the server "are these headers + method allowed?" The actual request only fires if the server approves. Preflights are invisible in most UI debuggers; check the Network tab to see them.
The most common CORS errors + fixes
- "No 'Access-Control-Allow-Origin' header is present." Server didn't set the header. Fix: add
Access-Control-Allow-Origin: https://yoursite.com(or*for public APIs) on the server. - "Credentials flag true, but Allow-Origin is *." For cookie-bearing requests, you must specify the exact origin, not wildcard. Fix: echo the request's
Originheader dynamically. - "Method PUT is not allowed." Server didn't include PUT in the preflight response. Fix:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS. - "Request header X is not allowed." Fix: add X to
Access-Control-Allow-Headers.
Why CORS exists at all
Without CORS, any website you visit could silently make authenticated requests to every other site you're logged into (your bank, your email) and read the responses. CORS + cookies + the same-origin policy together prevent that. It's annoying during development but fundamental to browser security.
CORS is not a server firewall
CORS only protects browsers. A Python or curl script ignores CORS entirely. If you need true access control, authenticate the request (API key, OAuth) on the server. CORS is about keeping untrusted JavaScript from impersonating trusted users — nothing more.
Related tools
When a CORS-related API call fails, the response often has a non-2xx status — look it up with HTTP status codes. To inspect the body that DID arrive (from the server's perspective), pretty-print with JSON formatter. For URL parameters that contain special characters, URL encoder/decoder.
Featured Tools
Try these free tools directly in your browser — no sign-up required.
HTTP Status Codes
Complete HTTP status code reference with explanations, use cases, and examples. Look up any HTTP response code from 1xx informational to 5xx server errors.
JSON Formatter
Format, beautify, and validate JSON instantly. Paste raw JSON and get a clean, indented, human-readable output with syntax error detection.
URL Encoder / Decoder
Encode or decode URLs and query strings instantly. Convert special characters to percent-encoding and back for safe URL transmission and debugging.