设置HTTP头(Setting HTTP headers)

2019-06-18 11:53发布

我想设置一个头在我的围棋网络服务器。 我使用的是gorilla/muxnet/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