DevTools Logo

CORS & API Headers Cheat Sheet

Quick reference for CORS and API headers: preflight requests, response headers, Authorization, caching, and common configurations.

Web & Network
cors
headers
http

Cross-Origin Resource Sharing (CORS) lets a browser call your API from another origin. The browser enforces it: the server must answer preflight and simple requests with the right Access-Control-* headers.

Simple vs Preflight

Table
Request typeHeaders that trigger preflightServer response
SimpleGET/POST/HEAD, no custom headers, Content-Type in text/plain, multipart/form-data, application/x-www-form-urlencodedNo preflight — response headers only
PreflightCustom headers, Content-Type: application/json, PUT/DELETE/PATCH, credentialsBrowser sends OPTIONS first; server must answer before the real request
http
OPTIONS /api/items HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization, content-type

Response Headers Reference

Table
HeaderMeaningTypical value
Access-Control-Allow-OriginWhich origin(s) may read the responsehttps://app.example.com (or *)
Access-Control-Allow-MethodsAllowed methods for the preflightGET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-HeadersAllowed request headersAuthorization, Content-Type
Access-Control-Expose-HeadersResponse headers readable by JSX-Total-Count, Link
Access-Control-Allow-CredentialsAllow cookies/auth with the requesttrue
Access-Control-Max-AgeCache the preflight answer (seconds)86400

Server Examples

bash
# Simple: allow one origin
curl -sI -H "Origin: https://app.example.com" https://api.example.com/health
# Expect: access-control-allow-origin: https://app.example.com
javascript
// Express
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "https://app.example.com");
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
  res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
  res.setHeader("Access-Control-Allow-Credentials", "true");
  res.setHeader("Access-Control-Max-Age", "86400");
  if (req.method === "OPTIONS") return res.sendStatus(204);
  next();
});
nginx
# NGINX
add_header Access-Control-Allow-Origin "https://app.example.com" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
if ($request_method = OPTIONS) { return 204; }

Authorization Headers

Table
SchemeHeaderExample
Bearer tokenAuthorization: Bearer <token>Authorization: Bearer eyJhbGciOi...
Basic authAuthorization: Basic <base64(user:pass)>Authorization: Basic YWRtaW46c2VjcmV0
API keyCustom header (common: X-API-Key)X-API-Key: sk_live_123
DigestAuthorization: Digest ...Legacy, rarely used today

Caching Headers

Table
HeaderPurposeExample
Cache-ControlCache directivespublic, max-age=3600
ETagValidator for conditional requests"33a64df5"
Last-ModifiedDate-based validatorWed, 11 Aug 2026 09:00:00 GMT
If-None-Match / If-Modified-SinceRequest-side validatorsmatch the ETag

Common Pitfalls

[!WARNING] Access-Control-Allow-Origin: * combined with Access-Control-Allow-Credentials: true is invalid — the browser will reject the response. With credentials you must echo the exact origin and set Vary: Origin.

[!TIP] Always send Vary: Origin when the allowed origin is dynamic; otherwise shared caches (CDNs) may serve one origin's CORS headers to everyone.

References