Cross-Origin Resource Sharing is a browser security mechanism that controls which websites can make requests to your API. By default, browsers block web pages from making requests to domains different from the one serving the page. CORS provides a way for servers to explicitly allow specific origins, methods, and headers in cross-origin requests.
How It Works
When JavaScript on app.example.com makes a fetch request to api.example.com, the browser adds an Origin header to the request. The server responds with Access-Control-Allow-Origin: app.example.com to permit the request. If the header is missing or lists a different origin, the browser blocks the response from reaching JavaScript.
For "non-simple" requests (those using methods other than GET/POST, custom headers, or JSON content types), the browser sends a preflight request first: an OPTIONS request asking the server what is allowed. The server responds with allowed origins, methods, headers, and how long the browser can cache this preflight result. Only after preflight approval does the actual request proceed.
Key CORS headers include Access-Control-Allow-Origin (which origins are permitted), Access-Control-Allow-Methods (which HTTP methods are allowed), Access-Control-Allow-Headers (which custom headers are accepted), and Access-Control-Allow-Credentials (whether cookies should be sent).
Why It Matters
CORS prevents malicious websites from making authenticated requests to APIs on a user's behalf. Without this protection, visiting a malicious page could trigger requests to your bank's API using your existing cookies, potentially transferring funds or exposing account data. This attack is called Cross-Site Request Forgery (CSRF).
In Practice
A React application on dashboard.myapp.com needs to call an API on api.myapp.com. The API's middleware adds CORS headers allowing requests from the dashboard domain. Preflight caching is set to 24 hours to minimize OPTIONS overhead. Credentials are enabled so authentication cookies travel with requests.
Troubleshooting
"No Access-Control-Allow-Origin header" means your server is not sending CORS headers for that origin. Using Access-Control-Allow-Origin: * allows any origin but disables credentials. Check that your server handles OPTIONS requests (many frameworks need explicit configuration). During development, use a proxy through your dev server (Next.js rewrites, Vite proxy) to avoid CORS entirely by making requests same-origin.