While working with a server using something like Go’s built-in Mux router (or any other one really), you might encounter this annoying error when you try to connect to your API running on a different port and you can’t simply throw your usual cors
middleware package in for some reason:
It’ll be even more annoying because it is not your typical CORS error and the requests are clearly not hitting your handler functions! Don’t worry, it is an easy fix. You just need to setup a catch-all endpoints that responds to the OPTION
method and returns the appropriate headers. In Robin which uses a single endpoint, it is handled this way:
// Handle CORS preflight requests
mux.HandleFunc("/"+i.route, func(w http.ResponseWriter, r *http.Request) {
if r.Method == "OPTIONS" {
if opts.PreflightHeaders != nil {
for k, v := range opts.PreflightHeaders {
w.Header().Set(k, v)
}
return
}
w.Header().Set("Access-Control-Allow-Origin", strings.Join(opts.Origins, ","))
w.Header().Set("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
}
})
For just the Pre-Flight
, you don’t necessarily need to provide all these (it depends on the browser and other things like whether you are sending credentials or not etc.), but the function this was extracted from is used for both the pre-flight and proper requests. That’s it, really, you can also just set the mode
to "no-cors"
in the fetch call as in:
fetch("http://foo.bar", {
method: "POST",
body: JSON.stringify({ d: "hello" }),
mode: "no-cors",
});
In case you are wondering how CorsOptions
is defined, here you go:
type CorsOptions struct {
// Allowed origins
Origins []string
// Allowed headers
Headers []string
// Allowed methods
Methods []string
// Exposed headers
ExposedHeaders []string
// Allow credentials
AllowCredentials bool
// Max age
MaxAge int
// Preflight headers
PreflightHeaders map[string]string
}