← Concepts

阅读中文版本

CORS

CORS is a browser-enforced mechanism that lets a server declare which origins may read its responses. It relaxes the same-origin policy without weakening server security.

security

Definition

Cross-Origin Resource Sharing is a browser security feature and HTTP header protocol that allows a server to permit JavaScript from selected origins to read its responses. The browser sends preflight requests for non-simple calls and enforces the returned allowlist; non-browser clients are unaffected.

Context and scope

CORS matters whenever a browser application calls an API on a different origin, such as a single-page app talking to a separate API domain. It also interacts with cookie credentials, CSRF defenses, and content security policy.

Common misconceptions

  • CORS protects an API from unauthorized clients rather than controlling browser read access
  • A wildcard origin can be combined with credentialed requests

Anti-patterns

  • Reflecting every incoming Origin header together with Access-Control-Allow-Credentials
  • Treating CORS configuration as a replacement for authentication or CSRF protection

Related concepts

Related examples

Authoritative source

https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS

How CORS works

Browsers enforce the same-origin policy: JavaScript from one origin cannot read responses from another unless the server opts in. CORS is that opt-in, expressed through response headers. For simple requests the browser sends the request and checks Access-Control-Allow-Origin before exposing the response. For non-simple methods, custom headers, or JSON content types, the browser first sends an OPTIONS preflight and waits for Access-Control-Allow-Methods and Access-Control-Allow-Headers. Credentialed requests require an explicit origin and Access-Control-Allow-Credentials: true; wildcards are rejected.

When to use it

Enable CORS when a browser application on one origin calls an API on another, for example https://app.example.com calling https://api.example.com, or a local development server calling staging. Server-to-server calls, curl, and native mobile HTTP clients are not subject to CORS. Keep the allowlist narrow and environment-specific rather than reflecting any Origin value.

Trade-offs

A permissive policy such as * is easy but incompatible with cookies and exposes responses to any site. A strict allowlist requires configuration per environment and breaks preview deployments unless handled. Preflights add a round trip; cache them with Access-Control-Max-Age. CORS does not authenticate users, rate-limit abuse, or stop CSRF, because the request may still reach the server even when the response is blocked.

Example

import cors from 'cors';

app.use(cors({
  origin: ['https://app.example.com'],
  methods: ['GET', 'POST'],
  credentials: true,
  maxAge: 600,
}));

CORS is not a server-side firewall: non-browser clients ignore it, and simple requests still reach the server. Access-Control-Allow-Origin: * cannot be combined with credentials. CSRF defenses remain necessary for cookie-authenticated writes, and CSP governs which origins a page may load resources from.