Golang + CORS. 是否可以全局设置?

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

Golang + CORS. Global setting somehow?

问题

我正在尝试使用这个小的Go示例https://github.com/jakecoffman/golang-rest-bootstrap,并且目前进展顺利。

我正在尝试添加CORS以允许我的前端应用访问。

这是我的Main.go代码:

func main() {

    var err error

    session, err = r.Connect(r.ConnectOpts{
        Address:  "localhost:28015",
        Database: "demo",
        MaxOpen:  40,
    })
    if err != nil {
        log.Fatalln(err.Error())
    }

    r := mux.NewRouter()
    users.Init(r, session)
    accounts.Init(r, session)

    r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
    })

    port := "9999" // os.Getenv("PORT")
    log.Println("Serving on", ":"+port)
    http.ListenAndServe(":"+port, context.ClearHandler(r))
}

它在根URL处允许CORS,但由于其他路由在控制器中处理,我似乎无法使CORS在那里起作用。

这是AccountController的一部分:

func NewAccountController(r *mux.Router, s AccountService) *AccountController {
    cont := AccountController{s}
    r.Handle("/accounts", cont)
    r.Handle("/accounts/{id}", cont)

    return &cont
}

以及:

func (a AccountController) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    code := http.StatusMethodNotAllowed
    var data interface{}

    defer func(c int) {
        log.Println(r.URL, "-", r.Method, "-", code, r.RemoteAddr)
    }(code)

    if r.URL.Path == "/accounts" {
        switch r.Method {
        case "GET":
            code, data = a.List(w, r)
        case "POST":
            code, data = a.Add(w, r)
        default:
            return
        }
    } else {
        switch r.Method {
        case "GET":
            code, data = a.Get(w, r)
        case "PUT":
            code, data = a.Update(w, r)
        case "DELETE":
            code, data = a.Delete(w, r)
        default:
            return
        }
    }

    w.WriteHeader(code)
    w.Header().Set("Content-Type", "application/json")

    err := json.NewEncoder(w).Encode(data)
    if err != nil {
        log.Println("Failed to write data:", err)
        code = http.StatusInternalServerError
    }
}

有什么想法或指点吗?

谢谢,

JB

英文:

I'm trying out this small Go example https://github.com/jakecoffman/golang-rest-bootstrap, and so far so good.

I'm trying to add CORS to allow my front-end app access.

Here is my Main.go

func main() {

	var err error

	session, err = r.Connect(r.ConnectOpts{
		Address:  "localhost:28015",
		Database: "demo",
		MaxOpen:  40,
	})
	if err != nil {
		log.Fatalln(err.Error())
	}

	r := mux.NewRouter()
	users.Init(r, session)
	accounts.Init(r, session)

	r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
	})

	port := "9999" // os.Getenv("PORT")
	log.Println("Serving on", ":"+port)
	http.ListenAndServe(":"+port, context.ClearHandler(r))
}

It allows CORS at the root url, but since the other routes are handled in the controllers I just can't seem to get CORS to work there as well.

Here is part of the AccountController

func NewAccountController(r *mux.Router, s AccountService) *AccountController {
	cont := AccountController{s}
	r.Handle("/accounts", cont)
	r.Handle("/accounts/{id}", cont)

 	return &cont
}

And

func (a AccountController) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	code := http.StatusMethodNotAllowed
	var data interface{}

	defer func(c int) {
		log.Println(r.URL, "-", r.Method, "-", code, r.RemoteAddr)
	}(code)

	if r.URL.Path == "/accounts" {
		switch r.Method {
		case "GET":
			code, data = a.List(w, r)
		case "POST":
			code, data = a.Add(w, r)
		default:
			return
		}
	} else {
		switch r.Method {
		case "GET":
			code, data = a.Get(w, r)
		case "PUT":
			code, data = a.Update(w, r)
		case "DELETE":
			code, data = a.Delete(w, r)
		default:
			return
		}
	}

	w.WriteHeader(code)
	w.Header().Set("Content-Type", "application/json")

	err := json.NewEncoder(w).Encode(data)
	if err != nil {
		log.Println("Failed to write data: ", err)
		code = http.StatusInternalServerError
	}
}

Any ideas or pointers would be great.

Thanks,

JB

答案1

得分: 4

你可以为此编写一个简单的中间件:

type CORSMiddleware struct {
    http.Handler
}

func (cm CORSMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "*")
    cm.Handler.ServeHTTP(w, r)
}

然后,你可以像这样使用它:

var h http.Handler = CORSMiddleware{cont}
r.Handle("/accounts", h)
r.Handle("/accounts/{id}", h)
英文:

You can make a simple middleware for that:

type CORSMiddleware struct {
	http.Handler
}

func (cm CORSMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
    cm.Handler.ServeHTTP(w, r)
}

Then, you can use it like that:

var h http.Handler = CORSMiddleware{cont}
r.Handle("/accounts", h)
r.Handle("/accounts/{id}", h)

huangapple
  • 本文由 发表于 2015年5月19日 20:21:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/30325483.html
匿名

发表评论

匿名网友

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

确定