Stage 6. CORS Fundamentals
CORS is a browser security mechanism that decides whether JavaScript from one origin may read a response from another origin. The key point is scope: CORS does not secure your API globally; it governs what browser-side code can access. That is why an API can return 200 while the frontend still cannot use the response.
To reason about CORS, start with origin definition: scheme + host + port. If any part differs, origins are different. So https://app.example.com and https://api.example.com are cross-origin even within the same parent domain.
In simple cases, browser sends the main request directly. In many real-world cases, browser sends a preflight OPTIONS request first, asking whether method, headers, and origin are allowed. If the server response lacks compatible Access-Control-Allow-* headers, browser blocks JavaScript access.
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, Content-Type
A common mistake is treating CORS as a one-time toggle. In practice, policy depends on environment, domain topology, authentication mode, and client behavior. Overly broad policy increases risk; overly strict policy breaks user flows after deployment. The reliable approach is minimum-required policy plus automated verification.
Credentials require special care. If cookies or credentialed requests are used, Access-Control-Allow-Origin: * cannot be combined with Access-Control-Allow-Credentials: true. Server must return an explicit origin value. This is a security boundary, not a browser quirk.
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Headers: Authorization,Content-Type
Access-Control-Allow-Credentials: true
It is also important to separate CORS from CSRF. CORS controls browser read access for cross-origin responses. CSRF protects against unwanted state-changing requests made on behalf of an authenticated user. They are related in web security discussions but solve different threats.
CORS debugging requires browser-level inspection, not only backend logs. You must inspect both preflight and main requests in DevTools. Backend may log a successful response while browser still blocks frontend access.
Practical scenario
After moving frontend to a new domain, profile data stopped loading for part of users. API metrics looked healthy with 200 responses. DevTools analysis showed preflight did not allow the Authorization header. Fixing CORS headers resolved the issue quickly, but only after the team stopped treating it as a business-logic bug. This case demonstrates that CORS is a contract layer that must be designed and tested explicitly.