Stage 6. CORS Fundamentals
CORS (Cross-Origin Resource Sharing) is a browser rule that decides whether JavaScript on one page may read a response from another origin. Important scope: CORS does not “secure the whole API.” It controls browser-side read access. That is why “server returned 200 but frontend still got a CORS error” is a normal real-world case.
1. What Origin Means in Simple Terms
An origin is scheme + host + port.
https://app.example.comandhttps://api.example.comare different origins.http://app.example.comandhttps://app.example.comare also different.- Same host with different ports is still cross-origin.
When origin differs, browser applies CORS checks.
2. CORS Flow Step by Step
| Step | What browser does | What server must do |
|---|---|---|
| 1. Origin check | Detects cross-origin request | Be ready to return CORS headers |
| 2. Preflight (sometimes) | Sends OPTIONS asking about method/headers | Return matching Access-Control-Allow-* |
| 3. Main request | Sends real GET/POST/... only if preflight is allowed | Return CORS headers on main response too |
| 4. Browser decision | Allows or blocks JS access to response | Policy must match real client behavior |
3. When Preflight Is Required
Preflight commonly appears for non-simple requests: methods like PUT/DELETE, custom headers such as Authorization, or special Content-Type values. Browser sends OPTIONS first.
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, Content-Type
If server response does not include compatible Access-Control-Allow-* headers, browser blocks JavaScript access to main response.
4. Minimal Practical CORS Header Set
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Headers: Authorization,Content-Type
Access-Control-Allow-Credentials: true
Practical rule: keep policy as narrow as possible. Do not open everything “just in case.”
5. Common Credentials Mistake
This combination is invalid for credentialed browser requests:
Access-Control-Allow-Origin: *Access-Control-Allow-Credentials: true
For cookie/credential flows, server must return an explicit origin value.
6. CORS vs Authentication vs CSRF
- CORS: controls browser JS read access to cross-origin responses.
- Authentication: verifies client identity (token/session).
- CSRF protection: prevents unwanted state-changing requests on behalf of a user.
These mechanisms are related but solve different threats.
7. How to Debug CORS Without Guessing
- Open DevTools →
Network. - Inspect both requests: preflight
OPTIONSand main request. - Compare
Origin,Access-Control-Request-*, andAccess-Control-Allow-*. - Verify whether cookies/credentials are used and whether
Allow-Originis explicit. - Only then investigate endpoint business logic.
Practical scenario
After moving frontend to a new domain, GET /profile started failing in browser with CORS errors, while backend logs looked healthy. Root cause was API Gateway: preflight response missed Access-Control-Allow-Headers: Authorization. Server still returned 200, but browser blocked JavaScript from using the follow-up request. After fixing CORS policy and adding an e2e check for this cross-origin path, the issue was resolved.