Ответ
CORS (Cross-Origin Resource Sharing, Совместное использование ресурсов между разными источниками) — это механизм, использующий дополнительные HTTP-заголовки, чтобы дать веб-приложению, работающему на одном домене (origin), право доступа к выбранным ресурсам с другого домена.
Браузеры из соображений безопасности блокируют межсайтовые HTTP-запросы, инициированные скриптами (политика Same-Origin). CORS — это стандарт, который позволяет серверу явно указать, какие внешние источники имеют право получать к нему доступ.
Как это работает на практике с Node.js/Express:
- Простой запрос (Simple Request): Для запросов GET/POST/HEAD с определёнными заголовками браузер сразу делает основной запрос, но проверяет заголовок
Access-Control-Allow-Originв ответе сервера. - Предварительный запрос (Preflight Request): Для «непростых» запросов (например, с кастомными заголовками или методом PUT/DELETE) браузер сначала отправляет запрос
OPTIONS(preflight) на тот же URL, чтобы проверить разрешённые методы и заголовки.
Базовая настройка CORS в Express с помощью middleware cors:
const express = require('express');
const cors = require('cors');
const app = express();
// Разрешить запросы с любого origin (для публичных API)
app.use(cors());
// Или настроить более строго
const corsOptions = {
origin: 'https://my-trusted-frontend.com', // Разрешить только конкретный домен
optionsSuccessStatus: 200, // Для старых браузеров
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
};
app.use(cors(corsOptions));
app.get('/api/data', (req, res) => {
res.json({ message: 'Этот ответ виден только с https://my-trusted-frontend.com' });
});
Важные нюансы:
- Заголовок
Access-Control-Allow-Origin: *несовместим с использованием учётных данных (куки, HTTP-аутентификация). В этом случае необходимо указывать конкретный origin. - CORS — это защита в браузере. Сервер должен самостоятельно валидировать Origin для предотвращения CSRF-атак и прямых запросов извне браузера (например, через cURL или Postman).
- Для обработки preflight-запросов
OPTIONSmiddlewarecorsавтоматически добавляет соответствующие заголовки.
Ответ 18+ 🔞
А, CORS! Ну это, блядь, классика, ядрёна вошь! Сидишь ты такой, пишешь фронтенд на одном домене, а твой бэкенд торчит на другом — и тут тебе браузер, как хитрая жопа, говорит: «Нет, дружок, не пущу!». Это и есть политика Same-Origin, ёпта.
А CORS — это такой стандартный способ сказать этому браузеру: «Да расслабься ты, чувак, это свои! Пусти!». По сути, сервер специальными заголовками в HTTP-ответе кричит: «Эй, браузер, вот этому фронту с адреса https://my-cool-app.com можно мои ресурсы таскать!».
Как эта хрень работает на практике, особенно с Node.js и Express?
Тут два сценария, и второй — просто пиздец какой замудрёный.
-
Простой запрос (Simple Request). Это когда всё по-честному: GET, POST или HEAD, и заголовки стандартные. Браузер сразу шлёт основной запрос, но потом, получив ответ, смотрит в заголовок
Access-Control-Allow-Origin. Если там звёздочка (*) или твой домен — пропускает. Если нет — тебе, дружок, в консоли красная ошибка, волнение ебать. -
Предварительный запрос (Preflight Request). А вот это уже ёперный театр! Если твой запрос «непростой» — скажем, ты метод PUT используешь или кастомный заголовок
X-Api-Keyприлепил — браузер, такой подозрительный, сначала шлёт запросOPTIONS(это и есть preflight) на тот же самый адрес. Мол, «сервер, отзовись, что тебе можно?». И только получив в ответе разрешения на методы и заголовки, он пошнёт настоящий, основной запрос. Доверия ебать ноль, но безопасно.
Теперь, как это впендюрить в Express с помощью middleware cors (а без него — самим headers прописывать, терпения ноль ебать):
const express = require('express');
const cors = require('cors'); // Ставим: npm install cors
const app = express();
// Самый простой и опасный вариант — разрешить ВСЕМ (для публичных API сойдёт)
app.use(cors()); // Теперь любой фронт с любого домена может к тебе стучаться
// А вот так делают нормальные люди — настраивают строго
const corsOptions = {
origin: 'https://my-very-trusted-frontend.com', // Только этому парню можно
optionsSuccessStatus: 200, // Костыль для древних IE, которые с 200-м статусом для OPTIONS тупят
methods: ['GET', 'POST', 'PUT', 'DELETE'], // Какие методы разрешены
allowedHeaders: ['Content-Type', 'Authorization'] // Какие заголовки можно слать
};
app.use(cors(corsOptions)); // Применяем настройки
app.get('/api/data', (req, res) => {
res.json({ message: 'Эти данные увидит только фронт с https://my-very-trusted-frontend.com' });
});
Важные нюансы, без которых сядешь в лужу:
- Запомни раз и навсегда: заголовок
Access-Control-Allow-Origin: *не дружит с учётными данными (куки, авторизация). Если ты в запросеcredentials: 'include'указываешь, то сервер должен в ответе прописать конкретный origin, а не звёздочку. Иначе — облом. - CORS — это защита исключительно в браузере. Это не волшебный щит от всех атак. Любой пидарас шерстяной с помощью cURL или Postman может слать запросы напрямую к твоему API, и CORS ему — как кот сука собаке. Поэтому серверу всё равно надо самому проверять Origin и валидировать запросы, чтобы не ловить CSRF-атаки.
- За preflight-запросы
OPTIONSmiddlewarecorsзаботится автоматически. Он сам добавит нужные заголовки в ответ. Без него пришлось бы вручную роут дляOPTIONSписать — ещё та сосалка.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶