Что такое HTTP-метод OPTIONS и его основное применение?

Ответ

OPTIONS — это один из стандартных HTTP-методов, который используется для описания параметров и возможностей взаимодействия с целевым ресурсом (URL).

Клиент может использовать OPTIONS для запроса информации о том, какие методы (GET, POST, PUT и т.д.) и заголовки поддерживаются сервером для данного ресурса, не инициируя при этом никаких действий с самим ресурсом.

Основное применение — CORS Preflight Request (предварительный запрос)

Это самый частый сценарий использования OPTIONS. Браузер автоматически отправляет OPTIONS-запрос перед "сложными" кросс-доменными запросами, чтобы проверить, разрешает ли сервер такой запрос.

"Сложным" запрос считается, если он:

  • Использует методы, отличные от GET, POST, HEAD.
  • Содержит заголовки, отличные от стандартных (например, Authorization, X-Custom-Header).
  • Имеет Content-Type, отличный от application/x-www-form-urlencoded, multipart/form-data или text/plain.

Как это работает:

  1. Браузер хочет отправить PUT запрос с заголовком Authorization с сайта A.com на API B.com/resource.
  2. Перед отправкой PUT, браузер автоматически посылает OPTIONS запрос на B.com/resource.
  3. Сервер B.com должен ответить на OPTIONS запрос, указав в заголовках ответа, что он разрешает метод PUT и заголовок Authorization с домена A.com (например, через Access-Control-Allow-Methods: PUT и Access-Control-Allow-Headers: Authorization).
  4. Если ответ на OPTIONS положительный, браузер отправляет основной PUT запрос.

Пример обработки в Go (net/http):

func handler(w http.ResponseWriter, r *http.Request) {
    // Устанавливаем общие заголовки для всех ответов
    w.Header().Set("Access-Control-Allow-Origin", "*") // В проде лучше указать конкретный домен

    // Обработка предварительного запроса
    if r.Method == http.MethodOptions {
        w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
        w.WriteHeader(http.StatusNoContent) // 204 No Content - стандарт для успешного preflight
        return
    }

    // Обработка основного запроса (GET, POST и т.д.)
    w.Write([]byte("Hello, world!"))
}

Примечание: В реальных приложениях для обработки CORS обычно используют готовые middleware-библиотеки (например, gorilla/handlers, rs/cors или встроенные в фреймворки вроде Gin/Echo), которые делают эту логику более надежной и простой в настройке.