dongxie8856
2017-04-05 13:20
浏览 334
已采纳

带有golang后端的CORS请求不起作用

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.

I've tried to set the CORS handling in my backend but it still doesn't work and I'm not getting why.

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. 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

图片转代码服务由CSDN问答提供 功能建议

我的实现遇到一些问题。 我有一个用Golang和UI(在Angular2中)编写的后端 ))。

我试图在后端设置CORS处理,但它仍然无法正常工作,我也不知道为什么。

这是我的代码:

 包main 
 
import(
“ log” 
“ net / http” 
 
“ github  .com / gorilla / mux“ 
” github.com/rs/cors"
)

var路由器* mux.Router 
 
func main(){
 router = mux.NewRouter()
 \  n HandleFuncEx(“ / authentication”,handleAuthentication)
 HandleFuncEx(“ / callA”,handleCallA)
 HandleFuncEx(“ / callB”,handleCallB)
 HandleFuncEx(“ / callC”,handleCallC)
 
处理程序:=  cors.New(cors.Options {
 AllowedOrigins:[] string {“ *”},
 AllowedMethods:[] string {“ GET”,“ POST”,“ PATCH”},
 AllowedHeaders:[] string {  “ a_custom_header”,“ content_type”},
})。Handler(router)
 http.ListenAndServe(“:8000”,handler)
 
} 
 
fun  c HandleFuncEx(模式字符串,处理程序func(http.ResponseWriter,* http.Request)){
 log.Println(“ handled function”,pattern)
 router.HandleFunc(pattern,handler)
} 
   
 
 

身份验证模式正确运行(UI首次调用)\其他所有调用均未通过预检请求。 为什么会这样? \ n

感谢大家的帮助!

编辑:

这是无效响应标题的示例:

  HTTP / 1.1 200 OK 
Vary:Origin 
Vary:Access-Control-Request-Method 
Vary:Access-Control-Request-Headers 
日期:Fri,07 Apr 2017 08:33  :12 GMT 
Content-Length:0 
Content-Type:文本/纯文本;  charset = utf-8 
   
 
 

这些是请求的标头:

  OPTIONS / users HTTP / 1.1 
Host  :/ *已由我的公司策略删除* / 
连接:keep-alive 
Access-Control-Request-Method:GET 
来源:/ *已由我的公司策略删除* / 
用户代理:Mozilla / 5.0(Macintosh;英特尔 Mac OS X 10_12_4)
AppleWebKit / 537.36(KHTML,例如Gecko)Chrome / 57.0.2987.133 Safari / 537.36 
访问控制请求标题:access_token 
接受:* / * 
推荐人:/ *已由我的公司政策删除*  / 
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 
   
 
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • dtkvlj5386 2017-04-07 09:08
    已采纳

    As Adrian pointed out, you need to add the OPTIONS Method to the AllowedMethods array.

    Please also consider to add Accept, Accept-Language and Content-Type to the AllowedHeaders as good practice.

    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:

    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 server

    r := mux.NewRouter()
    r.Handle("/authentication", handleAuthentication)
    
    http.Handle("/", &CORSRouterDecorator{r})
    

    et voilà.

    已采纳该答案
    打赏 评论
  • duanhuo3392 2017-04-05 15:09

    I use Negroni as middleware and this code:

    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"))
    }
    
    打赏 评论
  • dqs13465424392 2018-08-24 08:00

    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.

    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.

    Sorted.

    打赏 评论

相关推荐 更多相似问题