CORS失败:从Go后端到Docker镜像上的前端

huangapple go评论121阅读模式
英文:

CORS failure from Go backend to frontend on docker image

问题

所以我在本地运行一个后端服务器,并在Docker容器中的localhost:8080上运行前端。当我打开前端时,我得到以下错误:

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.

我在网上搜索了一下,看到了各种设置头文件的版本。但是没有一个有效。我现在的设置如下:

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
}

但是无论我设置什么,我始终得到相同的错误。有人知道为什么会出现这个错误以及如何解决吗?

英文:

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?

答案1

得分: 1

创建一个中间件:

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") != ""
}

将中间件包装在你的路由器周围:

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

希望能帮到你。

编辑于2023-06-26:

如jub0bs在评论中建议的那样,使用一个维护良好的cors包:

英文:

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:

huangapple
  • 本文由 发表于 2023年6月25日 11:08:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76548755.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定