Host
是http1.1版本添加的Header, 可以用于指定具体的Host,通常该Header的值会从URL中自动解析。例如我们请求http://httpbin.org/anything?pass=111
,返回的结果如下:
{
"args": {
"pass": "111"
},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Cache-Control": "no-cache",
"Host": "httpbin.org",
"Postman-Token": "d2d7c62b-8144-4926-88c3-5bb06b5d4a3a",
"User-Agent": "PostmanRuntime/7.13.0"
},
"json": null,
"method": "GET",
"origin": "111.111.111.111, 111.111.111.111",
"url": "https://httpbin.org/anything?pass=111"
}
Header
里Host
为自动填充的信息,本例中就是httpbin.org
。
但是如果我们请求IP的时候呢?通过解析工具得知httpbin.org
的IP为:34.230.136.58
,我们改去请求http://34.230.136.58/anything?pass=111
,得到的结果如下:
{
"args": {
"pass": "111"
},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Cache-Control": "no-cache",
"Host": "34.230.136.58",
"Postman-Token": "ef2f8e19-130e-477e-9da5-517c4d13fb95",
"User-Agent": "PostmanRuntime/7.13.0"
},
"json": null,
"method": "GET",
"origin": "111.111.111.111, 111.111.111.111",
"url": "https://34.230.136.58/anything?pass=111"
}
可以看到Host
变成了我们请求的IP地址。
但是上边两个示例并没有说明白Host
这个属性到底是干嘛的 - -。
让我们假象一种情况,也是实际中常见的情况:
一台机器上同一IP绑定了不同的域名(可以通过域名提供商设置,或者Nginx
),可能不同的域名解析出的IP都是111.111.111.111,那么这个时候Host
的值就很有用了,它可以用于区分到底是哪个站点。
由于我们平常大部分时候都是用过域名访问的,所以不用纠结这个问题。但是如果利用IP访问的话,就需要手动指定一下Host
了。
还比如某个IP通过Nginx
转发到了指定的服务,那么你想访问另一个服务时候怎么办呢?
要么改用域名访问,要么请求IP的时候修改Header
设置Host
的值为你想要访问的服务的域名。
但是,在Golang
中,利用req.Header.Set()
或req.Header.Add()
方法是无法设置Host
的值的,可以在http
包的request.go
文件Header
的声明注释内看到:
// For incoming requests, the Host header is promoted to the
// Request.Host field and removed from the Header map.
Header
的设置中把Host
给屏蔽掉了,需要利用Request.Host
来设置Host
值。Google一下,有人提过issue: net/http: Setting custom “Host” request header doesn’t have effect #7682,最后也只是改动了文档,并没有说明为什么这样做。可能是为了方便吧。。。
参考文献:
https://stackoverflow.com/questions/12864302/how-to-set-headers-in-http-get-request
net/http: Setting custom “Host” request header doesn’t have effect #7682
网络—一篇文章详解请求头Host的概念