Что такое Preflight запрос?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Preflight запрос?
Preflight запрос — это автоматический HTTP запрос типа OPTIONS, который браузер посылает ДО основного запроса при определенных условиях. Это часть механизма CORS (Cross-Origin Resource Sharing) для защиты пользователей.
Когда браузер отправляет preflight?
Brauzzer отправляет preflight запрос перед основным запросом, если:
- HTTP метод не простой — используется PUT, DELETE, PATCH (не GET, POST, HEAD)
- Пользовательские заголовки — добавлены заголовки кроме простых (Authorization, X-Custom-Header и т.д.)
- Content-Type не стандартный — например, application/json (не application/x-www-form-urlencoded, text/plain)
- Запрос содержит credentials — withCredentials: true
Пример: когда происходит preflight
// Этот запрос ВЫЗОВЕТ preflight
fetch("https://api.example.com/users", {
method: "DELETE", // ← Не простой метод
headers: {
"Content-Type": "application/json", // ← Не простой тип
"Authorization": "Bearer token123", // ← Пользовательский заголовок
},
credentials: "include" // ← Отправлять cookies
});
Вот что произойдет:
-
Шаг 1: Preflight запрос (автоматический)
OPTIONS /users HTTP/1.1 Origin: https://myapp.com Access-Control-Request-Method: DELETE Access-Control-Request-Headers: content-type, authorization -
Шаг 2: Сервер отвечает с CORS headers
Access-Control-Allow-Origin: https://myapp.com Access-Control-Allow-Methods: GET, POST, DELETE, PUT Access-Control-Allow-Headers: content-type, authorization Access-Control-Max-Age: 86400 -
Шаг 3: Если preflight прошел OK, браузер отправляет основной запрос
DELETE /users HTTP/1.1 Authorization: Bearer token123
Простой запрос (БЕЗ preflight)
// Этот запрос НЕ вызовет preflight
fetch("https://api.example.com/data", {
method: "GET", // Простой метод
headers: {
"Content-Type": "text/plain" // Простой тип
}
});
Почему это нужно?
Preflight защищает от потенциальных CSRF и XSS атак, давая серверу возможность:
- Проверить, разрешена ли такой запрос
- Убедиться, что клиент легитимный
- Отклонить небезопасные операции
Как оптимизировать preflight?
1. Используй Access-Control-Max-Age
Сервер может кэшировать preflight результаты:
// На сервере (Express)
app.options("*", cors({
origin: "https://myapp.com",
methods: ["GET", "POST", "PUT", "DELETE"],
allowedHeaders: ["Content-Type", "Authorization"],
maxAge: 86400 // 24 часа — кэш preflight результата
}));
Теперь в течение 24 часов браузер не будет отправлять preflight для одинаковых запросов.
2. Избегай пользовательских заголовков, если можно
// ❌ Вызовет preflight
fetch(url, {
method: "POST",
headers: {
"X-Custom-Header": "value"
}
});
// ✅ Не вызовет preflight (передаешь в body)
fetch(url, {
method: "POST",
body: JSON.stringify({
customHeader: "value"
})
});
3. Если возможно, используй GET вместо DELETE
// ❌ Вызовет preflight
fetch(url, { method: "DELETE" });
// ✅ Не вызовет preflight
fetch(url + "?action=delete", { method: "GET" });
В консоли браузера
Видишь в Network tab два запроса (OPTIONS + основной)? Это preflight в действии. Если видишь только основной запрос — значит, он был простым и preflight не нужен.
Итог
Preflight запрос — это защитный механизм, который браузер использует автоматически. Разработчик не может его отключить (это фича, не баг). Оптимизируй через Max-Age и упрощение заголовков.