Если вы не хотите переопределять свой маршрутизатор (если ваше приложение не настроено так, чтобы это поддерживалось, или вы хотите настроить CORS на маршруте по маршруту), добавьте обработчик OPTIONS для обработки запроса перед полетом ,
То есть с Gorilla Mux ваши маршруты будут выглядеть так:
accounts := router.Path("/accounts").Subrouter()
accounts.Methods("POST").Handler(AccountsCreate)
accounts.Methods("OPTIONS").Handler(AccountsCreatePreFlight)
Обратите внимание, что в дополнение к нашему обработчику POST мы определяем определенный обработчик метода OPTIONS .
А затем для фактической обработки метода предварительной проверки OPTIONS вы можете определить AccountsCreatePreFlight следующим образом:
// Check the origin is valid.
origin := r.Header.Get("Origin")
validOrigin, err := validateOrigin(origin)
if err != nil {
return err
}
// If it is, allow CORS.
if validOrigin {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers",
"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}
Что действительно заставило меня все это щелкнуть (в дополнение к собственному пониманию того, как работает CORS), так это то, что HTTP-метод предварительного запроса отличается от HTTP-метода реального запроса. Чтобы инициировать CORS, браузер отправляет предварительный запрос с опциями метода HTTP, который вы должны явно обработать в своем маршрутизаторе, а затем, если он получает соответствующий ответ "Access-Control-Allow-Origin": origin
(или «*» для всех) от вашего приложения, он инициирует фактический запрос.
Я также считаю, что вы можете делать «*» только для стандартных типов запросов (например, GET), но для других вам придется явно указать источник, как я делал выше.
w.Header().Add("Access-Control-Allow-Methods", "PUT") w.Header().Add("Access-Control-Allow-Headers", "Content-Type")