我想设置一个头在我的围棋网络服务器。 我使用的是gorilla/mux
和net/http
包。
我想设置Access-Control-Allow-Origin: *
允许跨域AJAX。
这里是我的Go代码:
func saveHandler(w http.ResponseWriter, r *http.Request) {
// do some stuff with the request data
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/save", saveHandler)
http.Handle("/", r)
http.ListenAndServe(":"+port, nil)
}
该net/http
包有文档描述发送HTTP请求头,好像它是一个客户-我不完全知道如何设置响应头?
Answer 1:
没关系,我理解了它-我使用的Set()
上的方法Header()
卫生署!)
我的处理现在看起来是这样的:
func saveHandler(w http.ResponseWriter, r *http.Request) {
// allow cross domain AJAX requests
w.Header().Set("Access-Control-Allow-Origin", "*")
}
也许这将帮助别人咖啡因有时剥夺我自己:)
Answer 2:
以上所有答案都是错误的,因为他们没有处理OPTIONS预检要求,解决的办法是重写MUX路由器的接口。 见AngularJS $ HTTP GET请求自定义标题失败(alllowed在CORS)
func main() {
r := mux.NewRouter()
r.HandleFunc("/save", saveHandler)
http.Handle("/", &MyServer{r})
http.ListenAndServe(":8080", nil);
}
type MyServer struct {
r *mux.Router
}
func (s *MyServer) 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, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}
// Stop here if its Preflighted OPTIONS request
if req.Method == "OPTIONS" {
return
}
// Lets Gorilla work
s.r.ServeHTTP(rw, req)
}
Answer 3:
不要使用“*”的起源,直到你真的需要一个完全公开的行为。
正如维基百科说 :
“值‘*’的特殊之处在于它不允许请求提供凭据,这意味着HTTP认证,客户端的SSL证书,也不允许发送的cookie。”
这意味着,你会得到很多的错误,尤其是在Chrome的时候,你会尝试实现例如一个简单的身份验证。
这里是一个修正的包装:
// Code has not been tested.
func addDefaultHeaders(fn http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if origin := r.Header.Get("Origin"); origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
}
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token")
w.Header().Set("Access-Control-Allow-Credentials", "true")
fn(w, r)
}
}
而且不要忘了所有这些头回复预检OPTIONS请求。
Answer 4:
设置一个适当的golang中间件,这样你就可以在任何端点重用。
助手类型和功能
type Adapter func(http.Handler) http.Handler
// Adapt h with all specified adapters.
func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
for _, adapter := range adapters {
h = adapter(h)
}
return h
}
实际中间件
func EnableCORS() Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if origin := r.Header.Get("Origin"); origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers",
"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}
// Stop here if its Preflighted OPTIONS request
if r.Method == "OPTIONS" {
return
}
h.ServeHTTP(w, r)
})
}
}
端点
REMEBER! 中间件获得applyed上相反的顺序(ExpectGET()首先获得火灾)
mux.Handle("/watcher/{action}/{device}",Adapt(api.SerialHandler(mux),
api.EnableCORS(),
api.ExpectGET(),
))
Answer 5:
我对于这种情况下创建包装:
func addDefaultHeaders(fn http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
fn(w, r)
}
}
Answer 6:
如果你不希望重写你的路由器 (如果你没有在支持此功能的方式配置您的应用程序,或者想通过路径基础的路线上配置CORS),添加一个OPTIONS处理程序来处理的飞行前请求。
即,与大猩猩复用你的路线将如下所示:
accounts := router.Path("/accounts").Subrouter()
accounts.Methods("POST").Handler(AccountsCreate)
accounts.Methods("OPTIONS").Handler(AccountsCreatePreFlight)
注意上面,除了我们的POST处理程序中, 我们定义一个特定选项的方法处理 。
然后到实际处理OPTIONS预检方法,你可以定义AccountsCreatePreFlight像这样:
// Check the origin is valid.
origin := r.Header.Get("Origin")
validOrigin, err := validateOrigin(origin)
if err != nil {
return err
}
// If it is, allow CORS.
if validOrigin {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers",
"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}
真正使这一切单击我(除了实际了解CORS是如何工作的)是一个预检请求的HTTP方法是从实际请求的HTTP方法不同。 要启动CORS,浏览器将使用HTTP方法选项,你必须在你的路由器显式处理,并预检请求,那么,如果收到相应的响应"Access-Control-Allow-Origin": origin
(或“*”从您的应用程序的所有),它启动的实际要求。
我也相信,你只能做“*”为标准类型的请求(即:GET),但对于其他人,你必须明确地设置原点就像我上面做的。
Answer 7:
我有同样的问题上面给出的解决方案,如上面所描述是正确的,建立我有如下:1)Angularjs为客户端2)Beego框架GO服务器
请按照以下要点1)CORS设置必须只去服务器2上启用)不要在angularJS添加任何类型头除了这
.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}])
在你去服务器添加CORS设定的要求开始得到处理,使预检要求收到200 OK之后,OPTIONS方法将被转换为GET,POST,PUT或什么都为你的请求类型之前。
Answer 8:
我知道这是在回答一个不同的扭曲,但是这不就是更多的Web服务器的关注? 例如,nginx的 ,可能会有帮助。
所述ngx_http_headers_module模块允许添加“过期”和“缓存控制”报头字段,和任意字段,到响应报头
...
location ~ ^<REGXP MATCHING CORS ROUTES> {
add_header Access-Control-Allow-Methods POST
...
}
...
在生产的去服务的前面添加Nginx的似乎比较明智。 它提供了授权,记录和修改请求了更多的功能。 此外,它提供了控制谁可以访问您的服务,而不是只的能力,但可以在你的应用程序特定位置指定不同的行为,如上文所示。
我可以去,为什么要使用Web服务器与你走的API,但我认为这是另一个讨论的话题。
文章来源: Setting HTTP headers