2

So I am running a backend server locally, and the frontend in a Docker container at localhost:8080. When I open the front end, I get:

Access to fetch at 'http://localhost:3000/myservice' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

I had a root around online and saw various versions of setting headers. None worked. The one i have now is like this:

func (m MyService) initializeRoutes() {
    m.router.HandleFunc(VERSION+"/stuff", corsHandler(b.getStuff)).Methods("GET")
}

func corsHandler(h http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Print("preflight detected: ", r.Header)
        w.Header().Add("Connection", "keep-alive")
        w.Header().Add("Access-Control-Allow-Origin", "*")
        w.Header().Add("Access-Control-Allow-Methods", "POST, OPTIONS, GET, DELETE, PUT")
        w.Header().Add("Access-Control-Allow-Headers", "content-type")
        w.Header().Add("Access-Control-Max-Age", "86400")

        // continue with my method
        h(w, r)
    }
}

func (m MyService) getStuff(w http.ResponseWriter, r *http.Request) {
    //Do what is required
}

But i get the same error from the start no matter what i seem to set. Anyone know why I am getting this and how to fix it?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
discodowney
  • 1,475
  • 6
  • 28
  • 58
  • Hope this helps. https://stackoverflow.com/questions/53298478/has-been-blocked-by-cors-policy-response-to-preflight-request-doesn-t-pass-acce. You have to handle your preflight (OPTIONS) request as `200` – PRATHEESH PC Jun 25 '23 at 03:45
  • 2
    Implementing CORS from scratch is error-prone. I urge you to use a CORS middleware library, such as [this one](https://github.com/jub0bs/fcors). – jub0bs Jun 25 '23 at 10:15

1 Answers1

1

Create a middleware:

func EnableCORS(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Add("Vary", "Origin")
        w.Header().Add("Vary", "Access-Control-Request-Method")

        if r.Header.Get("Origin") != "" {
            w.Header().Set("Access-Control-Allow-Origin", "*")
            if isPreflight(r) {
                w.Header().Set("Access-Control-Allow-Methods", "OPTIONS, PUT, PATCH, DELETE")
                w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type")

                w.WriteHeader(http.StatusOK)
                return
            }
            break
        }
        next.ServeHTTP(w, r)
    })
}
func isPreflight(r *http.Request) bool {
    return r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != ""
}

Wrap the middleware around your router:

r := http.NewServeMux()
http.ListenAndServe(":8080", EnableCors(r))

Hope that helps.

EDIT 2023-06-26:

As jub0bs recommended in the comments, use a cors package which is maintained like:

alexjoedt
  • 121
  • 5