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

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

CORS failure from Go backend to frontend on docker image

问题

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

  1. 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.

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

  1. func (m MyService) initializeRoutes() {
  2. m.router.HandleFunc(VERSION+"/stuff", corsHandler(b.getStuff)).Methods("GET")
  3. }
  4. func corsHandler(h http.HandlerFunc) http.HandlerFunc {
  5. return func(w http.ResponseWriter, r *http.Request) {
  6. log.Print("preflight detected: ", r.Header)
  7. w.Header().Add("Connection", "keep-alive")
  8. w.Header().Add("Access-Control-Allow-Origin", "*")
  9. w.Header().Add("Access-Control-Allow-Methods", "POST, OPTIONS, GET, DELETE, PUT")
  10. w.Header().Add("Access-Control-Allow-Headers", "content-type")
  11. w.Header().Add("Access-Control-Max-Age", "86400")
  12. // continue with my method
  13. h(w, r)
  14. }
  15. }
  16. func (m MyService) getStuff(w http.ResponseWriter, r *http.Request) {
  17. //Do what is required
  18. }

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

英文:

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:

  1. 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:

  1. func (m MyService) initializeRoutes() {
  2. m.router.HandleFunc(VERSION+"/stuff", corsHandler(b.getStuff)).Methods("GET")
  3. }
  4. func corsHandler(h http.HandlerFunc) http.HandlerFunc {
  5. return func(w http.ResponseWriter, r *http.Request) {
  6. log.Print("preflight detected: ", r.Header)
  7. w.Header().Add("Connection", "keep-alive")
  8. w.Header().Add("Access-Control-Allow-Origin", "*")
  9. w.Header().Add("Access-Control-Allow-Methods", "POST, OPTIONS, GET, DELETE, PUT")
  10. w.Header().Add("Access-Control-Allow-Headers", "content-type")
  11. w.Header().Add("Access-Control-Max-Age", "86400")
  12. // continue with my method
  13. h(w, r)
  14. }
  15. }
  16. func (m MyService) getStuff(w http.ResponseWriter, r *http.Request) {
  17. //Do what is required
  18. }

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

创建一个中间件:

  1. func EnableCORS(next http.Handler) http.Handler {
  2. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  3. w.Header().Add("Vary", "Origin")
  4. w.Header().Add("Vary", "Access-Control-Request-Method")
  5. if r.Header.Get("Origin") != "" {
  6. w.Header().Set("Access-Control-Allow-Origin", "*")
  7. if isPreflight(r) {
  8. w.Header().Set("Access-Control-Allow-Methods", "OPTIONS, PUT, PATCH, DELETE")
  9. w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type")
  10. w.WriteHeader(http.StatusOK)
  11. return
  12. }
  13. break
  14. }
  15. next.ServeHTTP(w, r)
  16. })
  17. }
  1. func isPreflight(r *http.Request) bool {
  2. return r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != ""
  3. }

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

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

希望能帮到你。

编辑于2023-06-26:

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

英文:

Create a middleware:

  1. func EnableCORS(next http.Handler) http.Handler {
  2. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  3. w.Header().Add("Vary", "Origin")
  4. w.Header().Add("Vary", "Access-Control-Request-Method")
  5. if r.Header.Get("Origin") != "" {
  6. w.Header().Set("Access-Control-Allow-Origin", "*")
  7. if isPreflight(r) {
  8. w.Header().Set("Access-Control-Allow-Methods", "OPTIONS, PUT, PATCH, DELETE")
  9. w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type")
  10. w.WriteHeader(http.StatusOK)
  11. return
  12. }
  13. break
  14. }
  15. next.ServeHTTP(w, r)
  16. })
  17. }
  1. func isPreflight(r *http.Request) bool {
  2. return r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != ""
  3. }

Wrap the middleware around your router:

  1. r := http.NewServeMux()
  2. 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:

确定