[英]CORS request with golang backend doesn't works
I'm facing some issue with my implementation.我的实施面临一些问题。 I have a backend written in Golang and the UI (in Angular2) which are on the same server.我有一个用 Golang 编写的后端和位于同一服务器上的 UI(在 Angular2 中)。
I've tried to set the CORS handling in my backend but it still doesn't work and I'm not getting why.我试图在我的后端设置 CORS 处理,但它仍然不起作用,我不明白为什么。
Here's my code:这是我的代码:
package main
import (
"log"
"net/http"
"github.com/gorilla/mux"
"github.com/rs/cors"
)
var router *mux.Router
func main() {
router = mux.NewRouter()
HandleFuncEx("/authentication", handleAuthentication)
HandleFuncEx("/callA", handleCallA)
HandleFuncEx("/callB", handleCallB)
HandleFuncEx("/callC", handleCallC)
handler := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "POST", "PATCH"},
AllowedHeaders: []string{"a_custom_header", "content_type"},
}).Handler(router)
http.ListenAndServe(":8000", handler)
}
func HandleFuncEx(pattern string, handler func(http.ResponseWriter, *http.Request)) {
log.Println("handled function", pattern)
router.HandleFunc(pattern, handler)
}
The authentication pattern works correctly (is the first called by the UI) all the others calls fails the preflight request.身份验证模式正常工作(是 UI 的第一个调用),所有其他调用都未通过预检请求。 Why is it happening?为什么会发生?
Thanks everybody for the help!感谢大家的帮助!
EDIT:编辑:
This is an example of a non-working response Headers:这是非工作响应标头的示例:
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Date: Fri, 07 Apr 2017 08:33:12 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8
And these are request's headers:这些是请求的标头:
OPTIONS /users HTTP/1.1
Host: /* Removed by my company policy */
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: /* Removed by my company policy */
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Access-Control-Request-Headers: access_token
Accept: */*
Referer: /* Removed by my company policy */
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,it;q=0.4,la;q=0.2
As Adrian pointed out, you need to add the OPTIONS
Method to the AllowedMethods
array.正如Adrian指出的那样,您需要将OPTIONS
方法添加到AllowedMethods
数组中。
Please also consider to add Accept
, Accept-Language
and Content-Type
to the AllowedHeaders
as good practice.还请考虑将Accept
、 Accept-Language
和Content-Type
到AllowedHeaders
作为良好做法。
If you don't want to use the github.com/rs/cors
package, you can write a simple CORS decorator middleware on your own like this:如果您不想使用github.com/rs/cors
包,您可以像这样自己编写一个简单的 CORS 装饰器中间件:
CORS decorator CORS 装饰器
import (
"net/http"
"github.com/gorilla/mux"
)
// CORSRouterDecorator applies CORS headers to a mux.Router
type CORSRouterDecorator struct {
R *mux.Router
}
// ServeHTTP wraps the HTTP server enabling CORS headers.
// For more info about CORS, visit https://www.w3.org/TR/cors/
func (c *CORSRouterDecorator) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if origin := req.Header.Get("Origin"); origin != "" {
rw.Header().Set("Access-Control-Allow-Origin", origin)
rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
rw.Header().Set("Access-Control-Allow-Headers", "Accept, Accept-Language, Content-Type, YourOwnHeader")
}
// Stop here if its Preflighted OPTIONS request
if req.Method == "OPTIONS" {
return
}
c.R.ServeHTTP(rw, req)
}
HTTP server HTTP服务器
r := mux.NewRouter()
r.Handle("/authentication", handleAuthentication)
http.Handle("/", &CORSRouterDecorator{r})
et voilà.等等。
I use Negroni as middleware and this code:我使用 Negroni 作为中间件,代码如下:
func main() {
c := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"POST", "GET", "OPTIONS", "PUT", "DELETE"},
AllowedHeaders: []string{"Accept", "content-type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization"},
})
router := mux.NewRouter()
router = routers.SetAuthRoute(router)
apiRoutes := routers.InitRoutes()
router.PathPrefix("/api").Handler(negroni.New(
negroni.HandlerFunc(controllers.ValidateTokenMiddleware),
negroni.Wrap(apiRoutes),
))
server := negroni.Classic()
server.Use(c)
server.UseHandler(router)
server.Run("0.0.0.0:" + os.Getenv("PORT"))
}
Similar to the other two responses, but I my case my project is hosted on cloud9 so I had a couple of tweaks to do.与其他两个响应类似,但我的案例是我的项目托管在 cloud9 上,所以我需要做一些调整。
This is the code i added:这是我添加的代码:
cor := cors.New(cors.Options{
AllowedOrigins: []string{"https://*.c9users.io", "http://myapp.c9users.io:8080", "https://*.c9.io"},
AllowedMethods: []string{"POST", "GET", "OPTIONS", "PUT"},
AllowedHeaders: []string{"Accept", "Accept-Language", "Content-Type"},
AllowCredentials: true,
Debug: true,
});
I had to add the extra http origin as Safari makes the initial options request using http instead of https.我不得不添加额外的 http 源,因为 Safari 使用 http 而不是 https 发出初始选项请求。
Sorted.排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.