2017-04-05 18 views
0

我在執行時遇到了一些問題。 我有一個在Golang中編寫的後端和在同一個服務器上的UI(在Angular2中)。通過golang後端執行CORS請求不起作用

我試圖在後端設置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

你可以分享一個鉻devtools截圖的選項請求失敗,請求發送,響應收到? – mkopriva

+0

在執行實際請求之前,CORS使用OPTIONS謂詞檢查請求是否允許跨域。您必須允許OPTIONS並使用成功代碼(2xx)進行響應。 – Adrian

回答

2

由於Adrian指出,您需要將OPTIONS方法添加到AllowedMethods陣列。

也請考慮將Accept,Accept-LanguageContent-Type添加到AllowedHeaders作爲良好的做法。

如果你不想使用github.com/rs/cors包,你可以寫上自己的一個簡單的CORS裝飾中間件這樣的:

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服務器

r := mux.NewRouter() 
r.Handle("/authentication", handleAuthentication) 

http.Handle("/", &CORSRouterDecorator{r}) 

etvoilà。

0

我使用內格羅尼作爲中間件和該代碼:

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")) 
}