Только вчера разбирался для своего проекта по учёту долгов
https://debtstracker.io/ и победил.
На OPTIONS надо возвращать 200 с заголовками и пустой ответ.
Я руководствовался
этой схемой:
Вот мой работающий код на Go:
func getOnly(handler HttpHandler) HttpHandler {
return func(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
if r.Method == "OPTIONS" { // Preflight request
origin := r.Header.Get("Origin")
switch origin {
case "http://localhost:8080":
case "http://localhost:8100":
case "https://debtstracker.local":
case "https://debtstracker.io":
case "":
BadRequest(c, w, errors.New("Missing required request header: Origin"))
return
default:
err := errors.New(fmt.Sprintf("Unknown origin: %v", origin))
log.Debugf(c, err.Error())
BadRequest(c, w, err)
return
}
log.Debugf(c, "Request 'Origin' header: %v", origin)
if accessControlRequestMethod := r.Header.Get("Access-Control-Request-Method"); accessControlRequestMethod != "GET" {
BadRequest(c, w, errors.New("Not a valid preflight request"))
return
}
responseHeader := w.Header()
responseHeader.Set("Access-Control-Allow-Methods", "GET")
if accessControlRequestHeaders := r.Header.Get("Access-Control-Request-Headers"); accessControlRequestHeaders != "" {
log.Debugf(c, "Request Access-Control-Request-Headers: %v", accessControlRequestHeaders)
responseHeader.Set("Access-Control-Allow-Headers", accessControlRequestHeaders)
} else {
log.Debugf(c, "Request header 'Access-Control-Allow-Headers' is empty or missing")
// TODO(security): Is it wrong to return 200 in this case?
}
responseHeader.Set("Access-Control-Allow-Origin", origin)
w.WriteHeader(200)
return
}
if r.Method != "GET" {
BadRequest(c, w, errors.New(fmt.Sprintf("Expecting to get request method GET, got: %v", r.Method)))
return
}
handler(w, r)
}
}