Glossary

Access-Control-Allow-Origin

HTTP response header · ACAO

An HTTP response header the server sends to tell the browser which origin is allowed to read the response body. The browser refuses to expose the body to JavaScript unless this header is present and matches (or is the wildcard).

Three valid values

You can't list multiple origins in this header — only one origin or *. To allow several, the server has to inspect the request's Origin and reflect a matching value.

When you also need Vary: Origin

If your server reflects different Access-Control-Allow-Origin values depending on the request, add Vary: Origin to the response so caches don't serve a value meant for one origin to a different origin. Without it, CDNs and browser caches will silently break CORS for some requests.

Example: doing it right

// Node / Express — reflects the request origin if it's on an allowlist
const ALLOWED = new Set([
  'https://app.example.com',
  'http://localhost:3000'
]);

app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (origin && ALLOWED.has(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Vary', 'Origin');
  }
  next();
});

Common mistakes

See also

CORS Origin Preflight Credentialed request Blog · Why am I getting a CORS error?