CORS (Cross-Origin Resource Sharing) is an HTTP-header-based mechanism that allows a server to indicate which origins other than its own are permitted to load its resources. It’s the browser’s way of relaxing the same-origin policy for legitimate cross-origin requests.
The same-origin policy
Browsers enforce the same-origin policy: JavaScript on https://app.example.com cannot fetch data from https://api.different.com by default. Two URLs share an origin only if their protocol, hostname, and port all match. This prevents malicious sites from reading data from other sites using your cookies.
CORS is the opt-in mechanism that lets servers say “yes, this other origin is allowed to read my responses.”
How CORS works
When a browser makes a cross-origin request, it adds an Origin header. The server responds with Access-Control-Allow-Origin to indicate permission:
Request:
GET /api/data HTTP/1.1
Origin: https://app.example.com
Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
If the response header doesn’t match the requesting origin, the browser blocks JavaScript from reading the response. The request still reaches the server — CORS is enforced by the browser, not the server.
Preflight requests
For “non-simple” requests (those using methods other than GET/POST/HEAD, custom headers, or JSON content types), the browser sends an OPTIONS preflight request first:
OPTIONS /api/data HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type, Authorization
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
The Max-Age header tells the browser to cache this preflight result, avoiding repeated OPTIONS requests.
Common CORS headers
Access-Control-Allow-Origin: Allowed origin(s). Use*for public APIs or a specific origin for authenticated requests.Access-Control-Allow-Methods: Permitted HTTP methods.Access-Control-Allow-Headers: Permitted request headers.Access-Control-Allow-Credentials: Set totrueto allow cookies/authorization headers. Cannot be used with*for the origin.Access-Control-Expose-Headers: Which response headers JavaScript can read.
Debugging CORS errors
The notorious "No 'Access-Control-Allow-Origin' header" error means the server isn’t sending the right headers. Check: Is the server actually setting the header? Does it match the exact origin (protocol + domain + port)? Is a preflight needed and handled?
Generate correct CORS headers with the CORS Header Generator and test your configuration with the CORS Tester.