使golang Gorilla CORS处理程序工作

时间:2016-12-06 00:40:12

标签: go cors gorilla servemux

我在这里设置相当简单,如下面的代码所述。但我无法让CurInstallProgressChanged CancelButtonClick InitializeWizard CurPageChanged 工作。我一直收到这个错误:

  

XMLHttpRequest无法加载http://localhost:3000/signup。回应       预检请求未通过访问控制检查:否'访问 -       Control-Allow-Origin'标头出现在请求的资源上。       因此,不允许原点“http://localhost:8000”访问。该       响应有HTTP状态代码403。

我确信我在这里缺少一些简单的东西。

这是我的代码:

CORS

7 个答案:

答案 0 :(得分:34)

请阅读Markus建议的链接,以及触发CORS飞行前请求的内容。

转机前请求:您可能拥有类似JSON的内容类型,或其他一些触发飞行前请求的自定义标头,您的服务器可能无法处理这些请求。如果您在前端使用常见的AJAX,请尝试添加此内容:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Requested-With

Gorilla' handlers.CORS()将设置合理的默认设置,让CORS的基础知识为您服务;但是,你可以(也许应该)以更实用的方式控制。

这里有一些入门代码:

headersOk := handlers.AllowedHeaders([]string{"X-Requested-With"})
originsOk := handlers.AllowedOrigins([]string{os.Getenv("ORIGIN_ALLOWED")})
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})

// start server listen
// with error handling
log.Fatal(http.ListenAndServe(":" + os.Getenv("PORT"), handlers.CORS(originsOk, headersOk, methodsOk)(router)))

答案 1 :(得分:16)

您应该创建一个CORSOption对象。例如,要允许任何来源,请使用此代码:

corsObj:=handlers.AllowedOrigins([]string{"*"})

然后将此对象传递给handle.CORS函数:

log.Fatal(http.ListenAndServe(":3000", handlers.CORS(corsObj)(router)))

为了测试它,您可以使用CURL:

curl -H "Origin: http://example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: X-Requested-With" \
-X OPTIONS --verbose http://127.0.0.1:3000

当它工作时你应该看到这些标题:

> Accept: */*
> Origin: http://example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With

最终代码在这里:https://play.golang.org/p/AOrlJsWhvf

更多信息:

答案 2 :(得分:14)

您可以在此处获取更多详细信息:"No 'Access-Control-Allow-Origin' header is present on the requested resource"关于此问题。

还可以尝试使用此处理程序:Go Cors Handler,它可以解决您的问题。我觉得这个问题更清晰,更容易解决。

double value = 0;
for (int x = 0; x < 12; x++) {
  value = value * 10 + 9;
  NSString *result = [NSString stringWithFormat: @"%.10g", value];
  NSLog(@"value = %@", result);
}

答案 3 :(得分:3)

根据jeremiah.trein的回答。

CORS过滤器在服务器端设置。请求可能与Postman一起使用,但在浏览器上失败,因为Postman不发送预检请求,而浏览器却可以。

设置CORS过滤器将使您可以配置后端应接受的来源,方法和标头。

此外,如果您的浏览器发出包含json有效负载的POST或PUT请求(这是很合理的),则需要在允许的标头中添加'Content-Type'

最后,handlers.CORS()(router)不仅可以与http.ListenAndServe功能一起使用,而且还可以与http.Handle()一起使用。

代码片段也可能像这样:

router := mux.NewRouter()

// do all your routes declaration

headersOK := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type"})
originsOK := handlers.AllowedOrigins([]string{"*"})
methodsOK := handlers.AllowedMethods([]string{"GET", "POST", "OPTIONS", "DELETE", "PUT"})

http.Handle("/", handlers.CombinedLoggingHandler(os.Stderr, handlers.CORS(headersOK, originsOK, methodsOK)(router)))

值得一提的是,我已经在Google Cloud Platform Standard AppEngine中成功使用了此代码段(而且我相信它也可以在Flex AppEngine中使用)。

答案 4 :(得分:0)

package main

import (
    "log"
    "net/http"

    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"
    "myApp/src/controllers"
       "github.com/rs/cors"
)

func main() {

     ac := new(controllers.AccountController)

    router := mux.NewRouter()
    router.HandleFunc("/signup", ac.SignUp).Methods("POST")
    router.HandleFunc("/signin", ac.SignIn).Methods("POST")
//cors optionsGoes Below
corsOpts := cors.New(cors.Options{
    AllowedOrigins: []string{"http://localhost:8100"}, //you service is available and allowed for this base url 
    AllowedMethods: []string{
        http.MethodGet,//http methods for your app
        http.MethodPost,
        http.MethodPut,
        http.MethodPatch,
        http.MethodDelete,
        http.MethodOptions,
        http.MethodHead,
    },

    AllowedHeaders: []string{
        "*",//or you can your header key values which you are using in your application

    },
})

    http.ListenAndServe(":3000", corsOpts.Handler(router))
}

答案 5 :(得分:0)

声明多路复用器对象后,将accessControlMiddleware作为中间件添加到声明的对象中。

func main(){
  ac := new(controllers.AccountController)

    router := mux.NewRouter()
    router.Use(accessControlMiddleware)
    router.HandleFunc("/signup", ac.SignUp).Methods("POST")
    router.HandleFunc("/signin", ac.SignIn).Methods("POST")
    http.ListenAndServe(":3000", corsOpts.Handler(router))
}

// access control and  CORS middleware
func accessControlMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            w.Header().Set("Access-Control-Allow-Origin", "*")
            w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS,PUT")
            w.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type")

                if r.Method == "OPTIONS" {
                    return
                }

                next.ServeHTTP(w, r)
            })
        }

答案 6 :(得分:0)

我意识到这是一个老问题,但是尽管如此,我还是花了30分钟来解决这个问题。

handler = handlers.CORS(
    // handlers.AllowedMethods([]string{"GET", "POST", "PUT"}),
    handlers.AllowedHeaders([]string{"Accept", "Accept-Language", "Content-Type", "Content-Language", "Origin"}),
    // handlers.AllowedOrigins([]string{"*"}),
)(handler)

注意事项:

  • AllowedMethods不会明确包含OPTIONS,这是CORS处理程序的一部分
  • 需要明确提及AllowedHeaders,*不是有效的通配符。典型的ajax库在请求类似Content-Type之类的内容时会发送application/json,因此也要添加它。
  • *是AllowedOrigin的默认值