我在实施方面遇到了一些问题。 我有一个用Golang写的后端和UI(在Angular2中),它们位于同一台服务器上。
我已经尝试在后端设置CORS处理但它仍然无法正常工作,而且我没有理解。
这是我的代码:
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)
}
身份验证模式正常工作(首先由UI调用) 所有其他呼叫都未通过预检请求。 为什么会这样?
感谢大家的帮助!
编辑:
这是一个非工作响应标题的示例:
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
这些是请求的标题:
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
答案 0 :(得分:3)
正如Adrian所指出的那样,您需要将OPTIONS
方法添加到AllowedMethods
数组中。
另请考虑将Accept
,Accept-Language
和Content-Type
添加到AllowedHeaders
作为良好做法。
如果您不想使用github.com/rs/cors
包,您可以自己编写一个简单的CORS装饰器中间件:
CORS decorator
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服务器
r := mux.NewRouter()
r.Handle("/authentication", handleAuthentication)
http.Handle("/", &CORSRouterDecorator{r})
etvoilà。
答案 1 :(得分:1)
与其他两个响应类似,但是我的情况是我的项目托管在cloud9上,所以我需要做一些调整。
这是我添加的代码:
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,
});
我必须添加额外的http来源,因为Safari使用http而不是https发出初始选项请求。
排序。
答案 2 :(得分:0)
我使用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"))
}