英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论