OPTIONS
Применение
Запрос OPTIONS получает список разрешённых методов и возможностей целевого ресурса, не выполняя над ним никаких действий. Сервер отвечает заголовком Allow, перечисляющим поддерживаемые методы.
Когда в качестве цели запроса используется звёздочка (*), запрос относится к серверу в целом, а не к конкретному ресурсу.
OPTIONS * HTTP/1.1
Host: api.example.re
Предварительный запрос CORS
Самое распространённое практическое применение OPTIONS — предварительный запрос (preflight) CORS. Перед отправкой межсайтового запроса с методом вне списка безопасных для CORS, с пользовательскими заголовками или с Content-Type вне безопасного списка (application/x-www-form-urlencoded, multipart/form-data, text/plain) браузер автоматически отправляет целевому серверу запрос OPTIONS. Предварительный запрос проверяет, разрешает ли сервер фактический запрос.
Предварительный запрос включает Origin, Access-Control-Request-Method и, опционально, Access-Control-Request-Headers. Сервер отвечает заголовками Access-Control-Allow-Origin, Access-Control-Allow-Methods и Access-Control-Allow-Headers, подтверждая разрешение.
Возможности ресурса
Клиент запрашивает разрешённые методы для конкретного ресурса. Сервер отвечает 204 No Content и заголовком Allow.
Запрос
OPTIONS /articles HTTP/1.1
Host: api.example.re
Ответ
HTTP/1.1 204 No Content
Allow: OPTIONS, GET, HEAD, POST, DELETE
Запрос по серверу целиком
Использование * в качестве цели раскрывает методы, которые сервер поддерживает в целом, независимо от какого-либо конкретного ресурса.
Запрос
OPTIONS * HTTP/1.1
Host: api.example.re
Ответ
HTTP/1.1 204 No Content
Allow: OPTIONS, GET, HEAD
Предварительный запрос CORS
Браузер готовит межсайтовый запрос PUT с пользовательским заголовком X-Request-ID. Перед отправкой фактического запроса браузер выполняет предварительный запрос OPTIONS, чтобы убедиться, что сервер разрешает этот метод и заголовок для запрашивающего источника.
Предварительный запрос
OPTIONS /api/data HTTP/1.1
Host: api.example.re
Origin: https://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Request-ID
Ответ на предварительный запрос
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: X-Request-ID
Access-Control-Max-Age: 86400
Значение Access-Control-Max-Age предписывает браузеру кэшировать результат предварительного запроса на 86 400 секунд (одни сутки), избавляя от повторных предварительных запросов к той же конечной точке.
Безопасность
Ответы OPTIONS содержат заголовок Allow со списком всех методов, которые поддерживает ресурс. Это незначительное раскрытие информации, и сканеры безопасности часто отмечают включённую конечную точку OPTIONS как находку. Полностью отключать OPTIONS непрактично, поскольку для работы предварительных запросов CORS требуется именно OPTIONS.
Рекомендуемый подход — ограничить заголовок Allow только теми методами, которые нужны каждой конечной точке. Ресурс, принимающий GET и POST, не должен объявлять DELETE или PUT в списке Allow.
Некоторые фреймворки поддерживают заголовок X-HTTP-Method-Override, позволяющий протуннелировать PUT, PATCH или DELETE через запрос POST. Это обходит контроль доступа на основе методов и представляет угрозу безопасности, если такая возможность не включена и не проверена осознанно.
Чтобы избежать лишних предварительных запросов, удерживайте межсайтовые запросы в рамках критериев «простого» запроса: только GET, HEAD или POST с безопасными заголовками и безопасными типами содержимого. Использование Content-Type: application/json всегда вызывает предварительный запрос. Access-Control-Max-Age кэширует результаты предварительных запросов, сокращая число повторных обращений OPTIONS.