使 golang Gorilla CORS 处理程序工作
Making golang Gorilla CORS handler work
我这里的设置相当简单,如下面的代码所述。但是我无法让 CORS
工作。我不断收到此错误:
XMLHttpRequest cannot load http://localhost:3000/signup. Response to
preflight request doesn't pass access control check: No 'Access-
Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:8000' is therefore not allowed access. The
response had HTTP status code 403.
我确定我在这里遗漏了一些简单的东西。
这是我的代码:
package main
import (
"log"
"net/http"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"myApp/src/controllers"
)
func main() {
ac := new(controllers.AccountController)
router := mux.NewRouter()
router.HandleFunc("/signup", ac.SignUp).Methods("POST")
router.HandleFunc("/signin", ac.SignIn).Methods("POST")
log.Fatal(http.ListenAndServe(":3000", handlers.CORS()(router)))
}
请阅读 link Markus 的建议,以及有关触发 CORS pre-flight 请求的内容。
Pre-flight 请求:您可能有类似 JSON 的内容类型,或触发 [=23] 的其他自定义 header =] 请求,您的服务器可能无法处理。如果您在 front-end 中使用 ever-common AJAX,请尝试添加这个:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Requested-With
Gorilla 的 handlers.CORS()
将设置合理的默认值,让 CORS 的基础知识为您所用;但是,您可以(也许应该)以更实用的方式进行控制。
这是一些入门代码:
// Where ORIGIN_ALLOWED is like `scheme://dns[:port]`, or `*` (insecure)
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)))
您应该创建一个 CORSOption
object。例如,要允许任何来源,请使用此代码:
corsObj:=handlers.AllowedOrigins([]string{"*"})
然后你将这个 object 传递给你的 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
当它工作时你应该看到那些 headers:
> Accept: */*
> Origin: http://example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
最终代码在这里:https://play.golang.org/p/AOrlJsWhvf
更多信息:
您可以在此处获得更多详细信息:Why doesn’t Postman get a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error when my JavaScript code does? 关于此问题。
也试试这个处理程序:Go Cors Handler 它应该可以解决您的问题。我发现这个问题更清晰,更容易解决。
package main
import (
"log"
"net/http"
"github.com/rs/cors"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"myApp/src/controllers"
)
func main() {
ac := new(controllers.AccountController)
router := mux.NewRouter()
router.HandleFunc("/signup", ac.SignUp).Methods("POST")
router.HandleFunc("/signin", ac.SignIn).Methods("POST")
c := cors.New(cors.Options{
AllowedOrigins: []string{"http://localhost:8000"},
AllowCredentials: true,
})
handler := c.Handler(router)
log.Fatal(http.ListenAndServe(":3000", handler)
}
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))
}
声明mux对象后,将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)
})
}
我意识到这是一个老问题,但我还是花了 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 库在请求 application/json
之类的内容时会发送 Content-Type
,因此也添加它。
*
是 AllowedOrigin 的默认值
基于jeremiah.trein的回答。
CORS 过滤器设置在服务器端。请求可能与 Postman 一起工作,但在浏览器上失败,因为 Postman 不发送预检请求,而浏览器发送。
设置 CORS 过滤器将允许您配置后端应接受的来源、方法和headers。
此外,如果您的浏览器发出 POST 或包含 json 有效负载的 PUT 请求(这是非常合理的),您需要将 'Content-Type'
添加到允许的headers.
最后,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 中使用)。
上述包github.com/rs/cors提供了构造函数
AllowAll() *Cors
那个
...create a new Cors handler with permissive configuration allowing all
origins with all standard methods with any header and credentials.
我这里的设置相当简单,如下面的代码所述。但是我无法让 CORS
工作。我不断收到此错误:
XMLHttpRequest cannot load http://localhost:3000/signup. Response to preflight request doesn't pass access control check: No 'Access- Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 403.
我确定我在这里遗漏了一些简单的东西。
这是我的代码:
package main
import (
"log"
"net/http"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"myApp/src/controllers"
)
func main() {
ac := new(controllers.AccountController)
router := mux.NewRouter()
router.HandleFunc("/signup", ac.SignUp).Methods("POST")
router.HandleFunc("/signin", ac.SignIn).Methods("POST")
log.Fatal(http.ListenAndServe(":3000", handlers.CORS()(router)))
}
请阅读 link Markus 的建议,以及有关触发 CORS pre-flight 请求的内容。
Pre-flight 请求:您可能有类似 JSON 的内容类型,或触发 [=23] 的其他自定义 header =] 请求,您的服务器可能无法处理。如果您在 front-end 中使用 ever-common AJAX,请尝试添加这个:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Requested-With
Gorilla 的 handlers.CORS()
将设置合理的默认值,让 CORS 的基础知识为您所用;但是,您可以(也许应该)以更实用的方式进行控制。
这是一些入门代码:
// Where ORIGIN_ALLOWED is like `scheme://dns[:port]`, or `*` (insecure)
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)))
您应该创建一个 CORSOption
object。例如,要允许任何来源,请使用此代码:
corsObj:=handlers.AllowedOrigins([]string{"*"})
然后你将这个 object 传递给你的 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
当它工作时你应该看到那些 headers:
> Accept: */*
> Origin: http://example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
最终代码在这里:https://play.golang.org/p/AOrlJsWhvf
更多信息:
您可以在此处获得更多详细信息:Why doesn’t Postman get a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error when my JavaScript code does? 关于此问题。
也试试这个处理程序:Go Cors Handler 它应该可以解决您的问题。我发现这个问题更清晰,更容易解决。
package main
import (
"log"
"net/http"
"github.com/rs/cors"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"myApp/src/controllers"
)
func main() {
ac := new(controllers.AccountController)
router := mux.NewRouter()
router.HandleFunc("/signup", ac.SignUp).Methods("POST")
router.HandleFunc("/signin", ac.SignIn).Methods("POST")
c := cors.New(cors.Options{
AllowedOrigins: []string{"http://localhost:8000"},
AllowCredentials: true,
})
handler := c.Handler(router)
log.Fatal(http.ListenAndServe(":3000", handler)
}
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))
}
声明mux对象后,将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)
})
}
我意识到这是一个老问题,但我还是花了 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 库在请求application/json
之类的内容时会发送Content-Type
,因此也添加它。 *
是 AllowedOrigin 的默认值
基于jeremiah.trein的回答。
CORS 过滤器设置在服务器端。请求可能与 Postman 一起工作,但在浏览器上失败,因为 Postman 不发送预检请求,而浏览器发送。
设置 CORS 过滤器将允许您配置后端应接受的来源、方法和headers。
此外,如果您的浏览器发出 POST 或包含 json 有效负载的 PUT 请求(这是非常合理的),您需要将 'Content-Type'
添加到允许的headers.
最后,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 中使用)。
上述包github.com/rs/cors提供了构造函数
AllowAll() *Cors
那个
...create a new Cors handler with permissive configuration allowing all origins with all standard methods with any header and credentials.