← Назад к вопросам

Что такое OPTIONS?

2.0 Middle🔥 201 комментариев
#Сетевые протоколы и API

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое HTTP-метод OPTIONS?

OPTIONS — это один из стандартных HTTP-методов (наряду с GET, POST, PUT, DELETE и другими), предназначенный для определения возможностей веб-сервера или поддерживаемых методов для конкретного ресурса. Согласно спецификации HTTP/1.1 (RFC 7231), метод OPTIONS используется для описания параметров коммуникации с целевым ресурсом.

Основное назначение и использование

Основная цель OPTIONS-запроса — запрос информации о доступных методах и настройках без выполнения каких-либо действий над ресурсом. Это особенно критично в контексте современных веб-приложений из-за двух ключевых сценариев:

  1. CORS (Cross-Origin Resource Sharing — Совместное использование ресурсов между разными источниками): Это самый распространённый случай использования в современной веб-разработке. Когда веб-приложение, загруженное с одного домена (например, https://frontend.com), пытается сделать "непростой" запрос (например, POST с определёнными заголовками) к API на другом домене (https://api.backend.com), браузер автоматически отправляет предварительный запрос (preflight request). Этот предварительный запрос использует метод OPTIONS, чтобы узнать, разрешён ли фактический запрос с точки зрения политики CORS.
    *   Сервер в ответе на OPTIONS должен вернуть заголовки, такие как `Access-Control-Allow-Methods`, `Access-Control-Allow-Headers`, `Access-Control-Allow-Origin`, информируя браузер о своих правилах.
    *   Только получив успешный ответ на OPTIONS, браузер отправит основной запрос (например, POST или PUT).

  1. Определение поддерживаемых методов HTTP для ресурса: Клиент может отправить OPTIONS-запрос к URI ресурса (или к "*" для всего сервера), чтобы понять, какие операции с ним можно выполнять. Сервер отвечает, указывая допустимые методы в заголовке Allow.

Пример запроса и ответа

Рассмотрим типичный сценарий CORS preflight-запроса.

Запрос OPTIONS от браузера:

OPTIONS /api/users HTTP/1.1
Host: api.example.com
Origin: https://myapp.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

Здесь браузер спрашивает: "Разрешено ли приложению с https://myapp.com отправлять POST-запрос на /api/users с заголовками Content-Type и Authorization?".

Успешный ответ сервера:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
Allow: GET, POST, PUT, DELETE, OPTIONS
  • Access-Control-Allow-Origin: Разрешает запросы с указанного источника.
  • Access-Control-Allow-Methods: Список методов, разрешённых для кросс-доменных запросов.
  • Access-Control-Allow-Headers: Список заголовков, которые клиент может использовать в основном запросе.
  • Access-Control-Max-Age: Указывает время в секундах, на которое браузер может закэшировать результат этого preflight-запроса (здесь — 24 часа), чтобы не отправлять OPTIONS перед каждым похожим запросом.
  • Allow: Стандартный HTTP-заголовок, указывающий методы, поддерживаемые ресурсом /api/users (для всех клиентов, не только CORS).

Обработка в Go (Golang)

В Go обработка OPTIONS-запросов часто реализуется на уровне маршрутизатора или middleware. Вот пример с использованием стандартной библиотеки net/http и популярного роутера gorilla/mux:

Пример middleware для CORS:

package main

import (
    "net/http"
    "github.com/gorilla/mux"
)

// CORS middleware
func enableCORS(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Устанавливаем заголовки для CORS
        w.Header().Set("Access-Control-Allow-Origin", "https://myapp.com")
        w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")

        // Если это предварительный OPTIONS-запрос, сразу отвечаем успехом
        if r.Method == "OPTIONS" {
            w.WriteHeader(http.StatusNoContent) // 204
            return
        }

        // Передаём управление следующему обработчику
        next.ServeHTTP(w, r)
    })
}

func main() {
    r := mux.NewRouter()

    // Применяем middleware ко всем маршрутам
    r.Use(enableCORS)

    // Объявляем маршруты API
    r.HandleFunc("/api/users", getUsers).Methods("GET")
    r.HandleFunc("/api/users", createUser).Methods("POST")

    http.ListenAndServe(":8080", r)
}

func getUsers(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Список пользователей"))
}

func createUser(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Пользователь создан"))
}

Важные технические детали

  • Безопасность и идемпотентность: OPTIONS считается безопасным (safe) и идемпотентным (idempotent) методом. Он не должен изменять состояние сервера, и многократные идентичные запросы должны давать один и тот же результат.
  • Коды состояния: Успешный ответ обычно имеет статус 200 OK (с телом, описывающим опции) или 204 No Content (как в примере CORS). Заголовок Allow является обязательным для успешного ответа на запрос к конкретному ресурсу.
  • Производительность: Частые OPTIONS-запросы могут создавать дополнительную нагрузку. Использование заголовка Access-Control-Max-Age позволяет браузерам кэшировать ответ, что значительно оптимизирует производительность SPA-приложений, делающих множество запросов к одному API.

Итог

Метод OPTIONS играет критически важную роль в современном вебе, выступая краеугольным камнем механизма CORS, который обеспечивает безопасное междоменное взаимодействие. Для Go-разработчика понимание OPTIONS необходимо для корректной настройки API, которое будет потребляться браузерными клиентами с других доменов. Обработка этого метода, как правило, выносится в CORS-middleware, что делает код чистым и поддерживаемым.