Golang + CORS。全球设置莫名其妙?

时间:2015-05-19 12:21:18

标签: go cors

我正在尝试这个小的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))
}

它允许根网址上的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

1 个答案:

答案 0 :(得分:3)

您可以为此制作一个简单的中间件:

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)