CORS (Cross-Origin Resource Sharing) — механизм, разрешающий JavaScript с одного origin (domain:port:scheme) запрашивать ресурсы с другого. Без CORS browsers блокируют fetch/XHR. Настройка: HTTP-заголовки Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers. Для credentials и non-simple requests — preflight (OPTIONS).
Ниже: пошаговая инструкция, рабочие примеры, типичные ошибки, FAQ.
* — только для public API без credentialsAccess-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Credentials: true + НЕ wildcardAccess-Control-Max-Age: 86400 (24h)| Сценарий | Конфиг |
|---|---|
| nginx simple CORS | 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; |
| nginx preflight | if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' '$http_origin';
add_header 'Access-Control-Max-Age' 86400;
return 204;
} |
| Apache .htaccess | Header set Access-Control-Allow-Origin "https://app.example.com"
Header set Access-Control-Allow-Credentials "true" |
| Express.js | app.use(cors({ origin: 'https://app.example.com', credentials: true })); |
| Whitelist multiple origins | map $http_origin $cors_origin {
default "";
"~^https?://(app|api)\.example\.com$" $http_origin;
}
add_header 'Access-Control-Allow-Origin' $cors_origin always; |
* + Credentials=true — browsers блокируют, silent failSimple request: GET/HEAD/POST + only standard headers (Accept, Content-Type in form/text). Без preflight OPTIONS, идёт сразу. Не simple = preflight обязателен.
Security spec: credentials (cookies) + wildcard = теоретически любой site может украсть sessions. Browsers блокируют комбинацию.
DevTools → Network → красный запрос → Headers. Console покажет "CORS policy: ..." с причиной. <a href="/cors">Enterno CORS checker</a> симулирует разные Origin headers.
<a href="/cors">Enterno CORS checker</a> — введите URL + Origin → увидите what headers returned.