iva*_*arg 33 go cors preflight
所以我在Go中编写这个RESTful后端,它将通过跨站点HTTP请求调用,即来自另一个站点服务的内容(实际上,只是另一个端口,但同源策略启动,所以我们这里) .
在这种情况下,用户代理在某些情况下会发送预检OPTIONS请求,以检查实际请求是否可以安全发送.
我的问题是如何在Go环境中最好地处理和充分响应这些预检请求.我设想的方式并不是很优雅,我想知道是否有其他方法可以解决这个问题.
使用标准net/http包,我可以检查处理程序func中的请求方法,也许是这样的:
func AddResourceHandler(rw http.ResponseWriter, r *http.Request) {
switch r.Method {
case "OPTIONS":
// handle preflight
case "PUT":
// respond to actual request
}
}
Run Code Online (Sandbox Code Playgroud)
我也可以使用Gorilla的 mux包,并为每个相关的URL路径注册预检"OPTIONS"处理程序.
r := mux.NewRouter()
r.HandleFunc("/someresource/item", AddResourceHandler).Methods("PUT")
r.HandleFunc("/someresource/item", PreflightAddResourceHandler).Methods("OPTIONS")
Run Code Online (Sandbox Code Playgroud)
也许对这个问题的回答很简单:是的,这些是你的基本选择.但我认为可能有一些最好的做法,我不知道.
pho*_*zed 30
分离逻辑并重新使用您定义的CORS处理程序的一种简单方法是包装REST处理程序.例如,如果你使用net/http和Handle方法,你总是可以这样做:
func corsHandler(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if (r.Method == "OPTIONS") {
//handle preflight in here
} else {
h.ServeHTTP(w,r)
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样包装:
http.Handle("/endpoint/", corsHandler(restHandler))
Run Code Online (Sandbox Code Playgroud)
这是一个对我有用的片段:
addCorsHeader(res)
if req.Method == "OPTIONS" {
res.WriteHeader(http.StatusOK)
return
} else {
h.APIHandler.ServeHTTP(res, req)
}
func addCorsHeader(res http.ResponseWriter) {
headers := res.Header()
headers.Add("Access-Control-Allow-Origin", "*")
headers.Add("Vary", "Origin")
headers.Add("Vary", "Access-Control-Request-Method")
headers.Add("Vary", "Access-Control-Request-Headers")
headers.Add("Access-Control-Allow-Headers", "Content-Type, Origin, Accept, token")
headers.Add("Access-Control-Allow-Methods", "GET, POST,OPTIONS")
}
Run Code Online (Sandbox Code Playgroud)
我个人觉得为每个获取OPTIONS请求的路径添加预检路由很繁琐,所以我只需将处理程序添加到OPTIONSGorilla处理的任何方法,如下所示:
router.Methods("OPTIONS").HandlerFunc(
func(w http.ResponseWriter, r *http.Request){
myHttpLib.OptionsForBrowserPreflight(w, r)
})
Run Code Online (Sandbox Code Playgroud)
但是请注意,这应该在映射其他路由之前进行,因为例如,如果您有一个类似的路径"/foo"并且首先注册该路径而不指定该路由的任何方法,那么对"/ foo"的OPTIONS请求将运行而不是您的预检代码,因为它的第一个匹配.
通过这种方式,您可以:(1)对所有预飞行只有一个路由注册,以及(2)有一个处理程序可以重用代码并在一个地方为OPTIONS请求应用逻辑/规则.
gorilla/handlers也有一个不错的 CORS 处理程序:cors.go
用法示例:
import (
"net/http"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/users", UserEndpoint)
r.HandleFunc("/projects", ProjectEndpoint)
// Apply the CORS middleware to our top-level router, with the defaults.
http.ListenAndServe(":8000", handlers.CORS()(r))
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19209 次 |
| 最近记录: |