golang'http.Request`的'Host'和'URL.Host'之间有什么区别?

golang'http.Request`的'Host'和'URL.Host'之间有什么区别?,http,go,Http,Go,在开发golang http应用程序时,我经常使用http.Request。当访问请求主机地址时,我会使用req.host,但我发现有req.URL.host字段,但当我打印它时,它是空的 func handler(w http.ResponseWriter, r *http.Request) { fmt.Println("uri Host: " + r.URL.Host + " Scheme: " + r.URL.Scheme) fmt.Println("Host: " + r

在开发golang http应用程序时,我经常使用
http.Request
。当访问请求主机地址时,我会使用
req.host
,但我发现有
req.URL.host
字段,但当我打印它时,它是空的

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Println("uri Host: " + r.URL.Host + " Scheme: " + r.URL.Scheme)
    fmt.Println("Host: " + r.Host)
}
的文档给出了以下注释,而
net/url
没有给出多少线索

// For server requests Host specifies the host on which the
// URL is sought. Per RFC 2616, this is either the value of
// the "Host" header or the host name given in the URL itself.
// It may be of the form "host:port". For international domain
// names, Host may be in Punycode or Unicode form. Use
// golang.org/x/net/idna to convert it to either format if
// needed.
//
// For client requests Host optionally overrides the Host
// header to send. If empty, the Request.Write method uses
// the value of URL.Host. Host may contain an international
// domain name.
Host string
在我看来,请求中有两个主机值:uri行和
host
头,如:

GET http://localhost:8080/ HTTP/1.1
Host: localhost:8080
但它并没有解决比它所造成的问题更多的问题:

  • 为什么请求中有两个不同的
    Host
    字段?我是说这不是一个复制品吗
  • 同一请求中的两个
    Host
    字段是否可以不同
  • 在什么情况下我应该使用哪一个

  • 用一个真实的HTTP请求示例来回答将是最好的。提前感谢。

    本质上
    http.Request.Host
    是为了方便

    r.Host
    r.Header.Get(“Host”)
    r.URL.Host
    更容易调用


    还需要注意的是,一些路由器将主机从
    http.Request.URL
    中剥离,因此
    http.Request.host
    在这些情况下也很有用

    因此,可以认为req.Host提供主机值,即使请求头或url已在别处修改。

    该字段是通过解析HTTP请求URI创建的

    该字段是的值。它的值与调用
    r.Header.Get(“主机”)
    的值相同

    如果连线上的HTTP请求为:

     GET /pub/WWW/TheProject.html HTTP/1.1
     Host: www.example.org:8080
    
    然后
    r.URL.Host
    是“”,而
    r.Host
    www.example.org:8080

    r.URL.Host
    r.Host
    的值几乎总是不同的。在代理服务器上,
    r.URL.Host
    是目标服务器的主机,
    r.Host
    是代理服务器本身的主机。当不通过代理连接时,客户端不会在请求URI中指定主机。在这个场景中,
    r.URL.Host
    是空字符串


    如果您没有实现代理,那么您应该使用
    r.Host
    来确定主机。

    “还需要注意的是,有些路由器会从http.Request.URL中删除主机”——不仅仅是路由器;代理也可以剥离或修改这些内容。