61、【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(五)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(四)

分析了 external_url 配置项在 Gitlab 中的作用,并开始分析 Gitlab 自带 Nginx 的 server_name 的作用,里面提到了 Host 字段的作用,下面继续分析

Nginx 配置审视

上篇 blog 提到了,Host 是 HTTP/1.1 协议中强制要求的请求头字段,用来告诉服务器,用户想访问的是机器上的哪个域名 ,使用浏览器访问 Web 服务,比如在发起 HTTP/1.1 请求时都会自动添加 Host 头,Host 值就是用户在地址栏输入的域名(或 IP + 端口),比如

  • http://www.example.com 对应 Host 为 www.example.com
  • https://api.myapp.com/v1/users 对应 Host 为 api.myapp.com
  • http://192.168.1.100:8080/test 对应 Host 为 192.168.1.100:8080

注意,如果 URL 中包含端口(不是默认的的 80/443),Host 就会包含端口号,就像上面第三点一样,而默认端口号不会写到 Host 里(即使 URL 里显式写了,浏览器在构造 Host 头时,也会省略掉默认端口)

从上面举例可以看出来,Host 请求头的值,就是 URL 中 :// 之后,到第一个 / 之前的部分,这部分内容包括域名 (比如 www.example.com),或 IP 地址 (比如 192.168.1.100),如果不是端口不是默认值(HTTP 80,HTTPS 443,之前 blog 【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(三) 介绍过),还要带上显式端口号,比如上面的 192.168.1.100:8080

这一点在官方文档 HTTP/1.1 规范 RFC 7230, Section 5.4 也能看到相关描述

可以看到,里面传达出几个关键信息:

  • 请求中的 Host 头字段,提供了目标 URI 中的主机名和端口信息(体现了用户想访问的网站名字,这个网站名字可以包含具体端口信息)
  • Host 头字段可以让 Web 服务器能够区分开不同的资源 ,比如同一台服务器上可能有成千上万个文件,页面和 API,但光靠路径,比如 /index.html 还远远不够,因为不同网站可能有同名路径,比如网站 A 有 siteA.com/index.html,网站 B 有 siteB.org/index.html,所以必须结合 host/path,也就是 Host + 路径才能唯一确定用户想要什么,而这里的 Host,就是告诉服务器,这个 index/html 路径到底是哪个站点的
  • Host 作用尤其体现在一台 Web 服务器(同一个 IP 地址)上,同时为多个域名提供服务时 ,这就是虚拟主机的核心场景,如果两个域名都指向同一个 IP,请求都发到这台 Web 服务器,服务器就可以靠 Host 头区分开,该返回那个站点的内容,可以说,没有 Host,就无法实现一机多站的功能,这正是现代 Web 能以低成本运行海量网站的基础技术之一

OK,理解了 Host 头,再看访问请求和 Nginx 配置块中的 server_name 是怎么互动的

可以看到,server_name 配置项和 Host 头就是匹配的,这意味着在写 server_name 时,和 Host 基本规则一样:

  • 首先,不需要也不应该默认端口,比如
bash 复制代码
server {
    listen *:80;
    server_name "example.com:80"; # 有问题,不要写默认端口
    
    # 其他配置...
}

这样就是错的,Nginx 不会匹配上 example.com 的域名,要把默认端口去掉

bash 复制代码
server {
    listen *:80;
    server_name "example.com"; # 这样 OK
    
    # 其他配置...
}
  • 另外,如果 Web 服务正在监听非标准端口(比如 8080),并且用户通过 http://example.com:8080 进行访问,那么 Host 头是 example.com:8080,这时可以用 listen + server_name 分离实现
bash 复制代码
server {
    listen *:8080;
    server_name "example.com";
    
    # 其他配置...
}

最后再总结下,Host 字段为 URL 中 :// 和第一个 / 之间,去掉协议默认端口后的内容,浏览器会自动设置 Host 字段,然后 Web 服务中 Nginx 会用这个 Host 字段去匹配 server_name 配置项,从而实现一台服务器托管多个网站的功能


OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog

相关推荐
ayqy贾杰6 分钟前
基层管理的三板斧,在AI时代行不通了
前端·后端·团队管理
Apifox7 分钟前
Apifox 5 月更新|Postman 导入优化、Runner 支持非 root 运行、请求代码自动带鉴权
前端·后端·安全
miaowmiaow18 分钟前
PSD2Code 近期更新与深度解析:从设计稿到生产级代码的完整技术栈
前端·人工智能·ai编程
Hilaku29 分钟前
多标签页并发请求导致 Token 刷新失败?只有 15行代码就能解决 !
前端·javascript·程序员
Nile37 分钟前
解密Palantir系列一:4. Ontology 不是哲学
开发语言·前端·javascript
因_崔斯汀1 小时前
ECharts 区域地图可视化实战:以山东地图为例
前端
Bacon1 小时前
手摸手带你搞清楚 AI Agent 的六大核心概念
前端·人工智能
王林不想说话1 小时前
TypeScript 进阶知识总结:从 extends、泛型到 infer,一篇打通 TS 类型系统
前端·javascript·typescript
罗超驿1 小时前
15.JavaScript 函数与作用域完全指南:语法、参数、表达式与作用域链实战
开发语言·前端·javascript
.千余1 小时前
【C++】C++类与对象2:C++构造函数、运算符重载与流输入输出全面解析
c语言·开发语言·前端·c++·经验分享