HTTP 协议 Host 请求头的作用

3 篇文章 0 订阅
2 篇文章 1 订阅

Host 是 HTTP 1.1 协议中新增的一个请求头,主要用来实现虚拟主机技术。

虚拟主机(virtual hosting)即共享主机(shared web hosting),可以利用虚拟技术把一台完整的服务器分成若干个主机,因此可以在单一主机上运行多个网站或服务。

举个栗子,有一台 ip 地址为 61.135.169.125 的服务器,在这台服务器上部署着谷歌、百度、淘宝的网站。为什么我们访问 https://www.google.com 时,看到的是 Google 的首页而不是百度或者淘宝的首页?原因就是 Host 请求头决定着访问哪个虚拟主机。

 

在使用tomcat的时候我们可以配置多个host,以此来实现一个web服务器上部署网站,每一个网站有不同的host,就像下面这样

<Host name="localhost"  appBase="webapps"
	unpackWARs="true" autoDeploy="true">

<Valve className="org.apache.catalina.authenticator.SingleSignOn" />

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
	   prefix="localhost_access_log" suffix=".txt"
	   pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>
<Host name="localhost1"  appBase="webapps1"
	unpackWARs="true" autoDeploy="true">

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
	   prefix="localhost_access_log" suffix=".txt"
	   pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

<!--
    需要注意的是,localhost1是不能被DNS解析到127.0.0.1的,这需要我们自己去配置host映射
    localhost不用进行配置,因为DNS会直接把该地址解析为127.0.0.1
-->

那么tomcat是如何知道把你的请求对应到哪个网站的呢?首先我们清楚我们的浏览器的一次请求,虽然我们写的是url,但是最后会被DNS解析成ip地址然后进行访问,所以说tomcat肯定不能使用请求url来进行判断,因为DNS解析之后我们请求的url就没有了。tcp/ip协议可不认识什么host,他也不知道你的请求地址,他只管把数据发送到对应ip的对应端口上去。所以说你直接发给tomcat的请求,他是不能知道到底要送到他内部的哪个网站去处理的,怎么进行判断呢?就是利用Http协议的Host请求头,根据请求头映射到对应的网站上,所以说我们一般的请求都会带上host请求头。

 

我们可以尝试一下,构建一个没有Host请求头的Http请求

public static void main(String[] args) throws UnsupportedEncodingException {
    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    // 创建Get请求
    HttpPost httpPost = new HttpPost("http://localhost:8080");
    httpPost.setHeader("Host", "111");
    // 响应模型
    CloseableHttpResponse response = null;
    Header[] allHeaders1 = httpPost.getAllHeaders();
    for (Header header : allHeaders1) {
        System.out.println(header);
    }
    try {
        response = httpClient.execute(httpPost);
        Header[] allHeaders = response.getAllHeaders();
        for (Header allHeader : allHeaders) {
            System.out.println(allHeader);
        }
        HttpEntity responseEntity = response.getEntity();
        System.out.println("响应状态为:" + response.getStatusLine());
        if (responseEntity != null) {
            System.out.println("响应内容长度为:" + responseEntity.getContentLength());
            System.out.println("响应内容为:" + EntityUtils.toString(responseEntity, "UTF-8"));
        }
    } catch (ParseException | IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (httpClient != null) {
                httpClient.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

可以发现能正常返回结果,为什么?因为tomcat中存在一个defaultHost,如下图

当没有任何的host能映射到我们对应的请求头,就会使用这个默认的host

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值