你可以使用`http.Response`结构体的`Header`字段来获取处理程序类型的响应头。

huangapple go评论89阅读模式
英文:

How can I get response headers from a Handler type?

问题

给定一个具有以下签名的中间件函数:

func Middleware(handler http.Handler) http.Handler

我如何从调用函数中获取设置并传递给它的响应头?

首先,使用一些响应头初始化一个HandlerFunc(“基础”或主服务器函数)。然后按照常规方式将其传递给中间件函数并进行包装。

我如何从handler参数中获取响应及其头部?

我尝试了很多方法,但无法获取头部的值。

英文:

Given a middleware function with a signature like:

func Middleware(handler http.Handler) http.Handler

How can I get response headers set and passed to it from a calling function?

First a HandlerFunc (the "base" or main server function) is initialized with some response headers. Then it is passed to and wrapped by the middleware function in the conventional manner.

How can I get the Response and its headers from the handler parameter?

I've tried a number of things but can't get at the header values.

答案1

得分: 3

严格来说,你不能直接从现有的http.Handler对象中获取HTTP请求或响应头。http.Handler实际上是一个被每个请求调用的函数。它并不绑定到任何特定的请求,而是会被用于任意数量的请求。因此,没有办法从现有的http.Handler对象中检索HTTP请求或响应头。

但是,你可以使用自己的中间件来装饰处理程序,以访问由中间件函数设置的HTTP响应头。

如你所描述的问题,中间件函数通常会这样实现:

func Middleware(originalHandler http.Handler) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
        // 调用被中间件包装的原始处理程序
        originalHandler.ServeHTTP(rw, req)
    })
}

这个函数会“装饰”传入中间件函数的原始http.Handler,通过返回一个新的处理程序来实现自定义逻辑,并在某个时刻调用原始(被包装的)处理程序。

在新的函数中,你可以像往常一样访问http.ResponseWriter对象,以访问已由装饰处理程序设置的HTTP头:

func Middleware(originalHandler http.Handler) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
        // 向响应添加新的头...
        rw.Header().Set("X-My-Own-Header", "foo")

        // ...或者访问原始请求中的数据
        fmt.Println(req.Header.Get("X-My-Request-Header"))

        // 调用被中间件包装的原始处理程序
        originalHandler.ServeHTTP(rw, req)

        // 在响应对象中访问头
        rw.Header().Get("X-Header-Set-By-Middleware")
    })
}
英文:

Strictly speaking, you cannot. In priniple, the http.Handler is a function that is invoked for each request. As such, it is not bound to any specific request; it will be re-used for an arbitrary number of requests. As such, there is no way to retrieve HTTP request or response headers from an existing http.Handler object.

You can however, decorate the handler with your own middleware to access HTTP response headers that were set by the middleware function.

A middleware function as described in your question will typically be implemented like this:

func Middleware(originalHandler http.Handler) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
        // call the original handler that is wrapped by this middleware
        originalHandler.ServeHTTP(rw, req)
    }
}

This function "decorates" the original http.Handler that is passed as a parameter into the middleware function by returning a new handler that implements custom logic and calls the original (wrapped) handler function at some point.

Within the new function, you can access the http.ResponseWriter object as usual to access the HTTP headers that were already set by the decorated handlers:

func Middleware(originalHandler http.Handler) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
        // Add new headers to the response...
        rw.Header().Set("X-My-Own-Header", "foo")

        // ...or access data from the original request
        fmt.Println(req.Header().Get("X-My-Request-Header")

        // call the original handler that is wrapped by this middleware
        originalHandler.ServeHTTP(rw, req)

        // Access headers in the response object
        rw.Header().Get("X-Header-Set-By-Middleware")
    }
}

huangapple
  • 本文由 发表于 2016年1月3日 02:48:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/34569457.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定