Cross-Origin Resource Sharing (CORS) is a browser security mechanism that controls how web pages can request resources from a different domain than the one that served the page. Understanding CORS is essential for any web developer building APIs or frontend applications that communicate across different origins.
CORS stands for Cross-Origin Resource Sharing, a standard defined by the W3C and enforced by all modern browsers. An 'origin' is the combination of a URL's protocol, domain, and port — for example, https://example.com:443. When a web page at one origin tries to fetch a resource from a different origin, the browser applies CORS rules to decide whether to allow it. Without CORS, browsers block these cross-origin requests by default under the Same-Origin Policy (SOP).
The Same-Origin Policy protects users from malicious sites silently reading sensitive data from other sites on their behalf — for example, a rogue page reading your bank's API using your session cookies. CORS provides a controlled way for servers to explicitly opt in to sharing their resources with trusted origins. This means security is server-declared rather than purely client-enforced, giving API owners fine-grained access control.
For 'simple' requests (GET, POST with certain content types), the browser sends the request with an Origin header and checks the server's Access-Control-Allow-Origin response header. If the header matches the requesting origin or is a wildcard (*), the browser allows the response to be read. For more complex requests — such as PUT, DELETE, or requests with custom headers — the browser first sends an HTTP OPTIONS 'preflight' request to ask the server for permission before sending the real request. The server must respond with the appropriate CORS headers, including Access-Control-Allow-Methods and Access-Control-Allow-Headers, for the actual request to proceed.
Access-Control-Allow-Origin specifies which origins may read the response, either a specific origin or * for public resources. Access-Control-Allow-Methods lists the HTTP methods the server permits, while Access-Control-Allow-Headers lists allowed request headers. Access-Control-Allow-Credentials must be set to true (and the origin must be explicit, not *) if the browser should include cookies or HTTP authentication in the cross-origin request.
A wildcard (*) in Access-Control-Allow-Origin cannot be combined with Access-Control-Allow-Credentials: true — the browser will block it, so always specify an explicit origin when credentials are involved. Avoid reflecting the incoming Origin header back verbatim without a whitelist, as this effectively disables origin checking and creates a security vulnerability. Configure CORS at the server or API gateway level, not the frontend, since any client-side workaround is trivially bypassed. Caching preflight responses with Access-Control-Max-Age reduces latency by telling the browser how long it can reuse the preflight result without making another OPTIONS request.
© RM Full Stack & AI Engineer · All guides · Roadmaps · Open the app