golang中`http.Request`的`Host`和`URL.Host`有什么区别?

30

在开发 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)
}

http.Request 的文档给出了以下注释,而 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头部,例如:

看起来对我来说,在一个请求中有两个主机值:URI行和Host头部,就像:

GET http://localhost:8080/ HTTP/1.1
Host: localhost:8080

但它所创造的问题比解决的问题更多:

  1. 请求中为什么会有两个不同的Host字段?这不是重复了吗?
  2. 在同一请求中,这两个Host字段可以不同吗?
  3. 在什么情况下应该使用哪一个?

最好附上一个真实的HTTP请求示例作为答案。谢谢。

1个回答

50

r.URL字段通过解析HTTP请求URI而创建。

r.Host字段是Host请求头的值。它与调用r.Header.Get("Host")的值相同。

如果HTTP请求在传输中:

 GET /pub/WWW/TheProject.html HTTP/1.1
 Host: www.example.org:8080

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接