HTTP/1.1 host虚拟主机详解

一、核心需求:为什么需要虚拟主机?

在互联网上,我们常常希望在一台物理服务器(它通常只有一个公网 IP 地址)上运行多个独立的网站,每个网站都有自己独特的域名(例如 www.a-site.com​, www.b-site.org​ 等)。如果每个网站都需要一个独立的 IP 地址,那将是非常昂贵且浪费 IPv4 资源的。

虚拟主机 (Virtual Hosting) 技术应运而生,它允许你在单一 IP 地址的服务器上,经济高效地托管多个使用不同域名的网站。

二、关键的“指路人”:Host​ 请求头部

HTTP/1.1 协议规定了一个强制性的请求头部字段——Host​。

  • 它的作用:当你的浏览器向服务器发送请求时(比如访问 http://www.a-site.com​),Host​ 头部会明确地告诉服务器,用户实际想要访问的目标域名是 www.a-site.com​。
  • 为何如此重要:如果请求中缺失 Host​ 头部,服务器虽然知道请求是发给自己的(通过 IP 地址判断),但它无法分辨这个请求究竟是针对它上面托管的哪一个网站。这就像一个快递员只知道包裹要送到某栋大楼,却不知道具体是哪家公司签收。服务器此时通常会返回错误,或者将请求导向一个预设的默认站点,但这往往不是用户期望的结果。

三、Nginx 实现虚拟主机的步骤

Nginx 作为一款高性能的 Web 服务器,通过其灵活的配置完美支持虚拟主机。主要涉及两大步骤:

1. DNS 配置:万流归宗

你需要将所有希望托管在这台 Nginx 服务器上的域名,都通过 DNS 解析指向这台服务器的同一个 IP 地址。

  • 例如,服务器 IP 为 100.200.10.20​。
  • 在你的 DNS 服务商处,为 www.a-site.com​、www.b-site.org​ 以及其他所有相关域名创建 A 记录,都指向 100.200.10.20​。
  • 结果:无论用户访问哪个域名,请求最终都会被发送到 IP 地址为 100.200.10.20​ 的这台 Nginx 服务器。

2. Nginx 服务器配置:精细分发

Nginx 的核心在于其配置文件(通常是 nginx.conf​ 以及通过 include​ 指令引入的其他配置文件,如 sites-available/​ 或 conf.d/​ 目录下的 .conf​ 文件)。Nginx 使用 server​ 配置块来为每一个虚拟主机(即每一个网站)定义一套独立的服务规则。

  • ​server​ 块:每个你想托管的网站都需要一个专属的 server { ... }​ 配置块。

    # 示例:/etc/nginx/sites-available/a-site.conf
    server {listen 80; # 监听标准的 HTTP 80 端口# listen 443 ssl; # 如果是 HTTPS,监听 443 端口server_name www.a-site.com a-site.com; # <--- 核心!指定此 server 块处理的域名root /var/www/a-site.com/public; # 网站文件的根目录index index.html index.php;      # 默认的索引文件access_log /var/log/nginx/a-site.com.access.log; # 独立的访问日志error_log /var/log/nginx/a-site.com.error.log;   # 独立的错误日志location / { # 处理根路径及所有未明确匹配的路径try_files $uri $uri/ =404; # 尝试查找文件或目录,否则返回404}# 可以为 a-site.com 添加更多特定的 location 规则、反向代理等# 例如,处理 PHP 文件# location ~ \.php$ {#     include snippets/fastcgi-php.conf;#     fastcgi_pass unix:/run/php/php8.0-fpm.sock;# }
    }# 示例:/etc/nginx/sites-available/b-site.org.conf
    server {listen 80;server_name www.b-site.org b-site.org; # <--- 另一个域名的 server 块root /var/www/b-site.org/html; # 不同的网站文件根目录index index.html;access_log /var/log/nginx/b-site.org.access.log;error_log /var/log/nginx/b-site.org.error.log;location /special-app/ {# 为 b-site.org 的某个特定应用做配置# proxy_pass http://localhost:5000;}# ... 其他 b-site.org 的配置
    }
    
  • 关键指令解释:

    • ​listen​:指定 Nginx 在哪个 IP 地址(可选)和哪个端口上监听请求。对于公共网站,这通常是 80​ (HTTP) 和/或 443​ (HTTPS)。
    • ​server_name​:这是 Nginx 区分虚拟主机的最关键指令。Nginx 会提取客户端 HTTP 请求中的 Host​ 头部的值,并将其与各个 server​ 块中 server_name​ 定义的域名列表进行匹配。匹配成功后,该 server​ 块内的其他指令就会生效。server_name​ 可以包含一个或多个域名,支持通配符和正则表达式。
    • ​root​:定义了当前 server​ 块所服务的网站的文档根目录(即网页文件存放的起始位置)。
    • ​index​:指定当用户请求一个目录时,Nginx 应尝试提供的默认文件名。
    • ​access_log​, error_log​:允许为每个虚拟主机配置独立的日志文件,方便管理和问题排查。
    • ​location​ 块:允许你针对特定的 URL 路径或模式(如图片、API 接口、PHP 文件等)定义更细致的处理规则。
  • 启用配置:通常将写好的虚拟主机配置文件从 sites-available​ 目录链接到 sites-enabled​ 目录,然后测试配置(sudo nginx -t​)并重载 Nginx(sudo systemctl reload nginx​)。

四、工作流程回顾

  1. 用户在浏览器输入 http://www.a-site.com/contact.html​。
  2. DNS 将 www.a-site.com​ 解析到 Nginx 服务器的 IP 地址 (100.200.10.20​)。
  3. 浏览器向 100.200.10.20:80​ 发送 HTTP 请求,请求头中包含 Host: www.a-site.com​。
  4. Nginx 收到请求,读取 Host​ 头部为 www.a-site.com​。
  5. Nginx 遍历其加载的所有 server​ 块,查找 server_name​ 指令中包含 www.a-site.com​ (或匹配的通配符/正则) 的那个 server​ 块。
  6. 一旦匹配成功(例如,匹配到 /etc/nginx/sites-available/a-site.conf​ 中的 server​ 块),Nginx 就会使用该 server​ 块内的配置来处理请求(例如,从 /var/www/a-site.com/public​ 目录中查找 contact.html​ 文件)。
  7. Nginx 将找到的内容作为响应返回给浏览器。

如果另一个请求的 Host​ 头部是 www.b-site.org​,Nginx 则会匹配到为 b-site.org​ 配置的 server​ 块,并按其规则提供服务。

五、对比:“IP + 不同端口”方案的局限性

你可能会想,为什么不直接用 IP 地址配合不同的端口号来区分不同的网站呢?例如:

  • ​www.a-site.com​ -> 100.200.10.20:8080​
  • ​www.b-site.org​ -> 100.200.10.20:8081​

技术上这完全可行,Nginx 的 listen​ 指令可以直接监听这些非标准端口。但这种方式对于公共访问的网站来说,并非理想选择,主要原因如下:

  1. 用户体验差:用户访问网站时,必须在浏览器地址栏中手动输入非标准的端口号(如 http://www.a-site.com:8080​)。这非常不方便,也容易出错。

  2. 浏览器默认行为:当用户只输入域名(如 www.a-site.com​)或使用标准的 http://​ / https://​ 前缀时,浏览器会自动连接到服务器的标准端口:

    • HTTP: 默认连接端口 80​
    • HTTPS: 默认连接端口 443​
      如果你的网站运行在非标准端口,用户不显式指定端口就无法访问。
  3. DNS 限制:标准的 DNS A 记录只负责将域名解析到 IP 地址,不包含端口信息。虽然 SRV 记录可以指定服务端口,但浏览器在访问常规网站时并不依赖它。

结论:Host​ 头部虚拟主机的优越性

基于 Host​ 头部的虚拟主机(通常都监听在标准的 80 和 443 端口)是托管多个公共网站的行业标准和最佳实践。它对用户完全透明,用户只需输入域名即可访问,而服务器则在后端通过 Host​ 头部智能地将请求分发给正确的网站进行处理。这种方式既高效、经济,又保证了良好的用户体验。

“IP + 不同端口”的方案更适用于内部服务、API 接口、或者一些用户明确知道需要指定端口的特定应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/80465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

amass:深入攻击面映射和资产发现工具!全参数详细教程!Kali Linux教程!

简介 OWASP Amass 项目使用开源信息收集和主动侦察技术执行攻击面网络映射和外部资产发现。 此软件包包含一个工具&#xff0c;可帮助信息安全专业人员使用开源信息收集和主动侦察技术执行攻击面网络映射并执行外部资产发现。 使用的信息收集技术 技术数据来源APIs&#xf…

Spring Web MVC响应

返回静态页面 第一步 创建html时&#xff0c;要注意创建的路径&#xff0c;要在static下面 第二步 把需要写的内容写到body内 第三步 直接访问路径就可以 返回数据ResponseBody RestController Controller ResponseBody Controller&#xff1a;返回视图 ResponseBody&…

‌鸿蒙PC正式发布:国产操作系统实现全场景生态突破

鸿蒙PC正式发布&#xff1a;国产操作系统实现全场景生态突破‌ 2025年5月8日&#xff0c;华为在深圳举办发布会&#xff0c;正式推出搭载鸿蒙操作系统的个人电脑&#xff08;PC&#xff09;&#xff0c;标志着国产操作系统在核心技术与生态布局上实现历史性跨越。此次发布的鸿蒙…

【计算机视觉】OpenCV实战项目:Text-Extraction-Table-Image:基于OpenCV与OCR的表格图像文本提取系统深度解析

Text-Extraction-Table-Image&#xff1a;基于OpenCV与OCR的表格图像文本提取系统深度解析 1. 项目概述2. 技术原理与算法设计2.1 图像预处理流水线2.2 表格结构检测算法2.3 OCR优化策略 3. 实战部署指南3.1 环境配置3.2 核心代码解析3.3 执行流程示例 4. 常见问题与解决方案4.…

Redis BigKey 问题是什么

BigKey 问题是什么 BigKey 的具体表现是 redis 中的 key 对应的 value 很大&#xff0c;占用的 redis 空间比较大&#xff0c;本质上是大 value 问题。 BigKey怎么找 redis-cli --bigkeysscanBig Key 产生的原因 1.redis数据结构使用不恰当 2.未及时清理垃圾数据 3.对业务预…

go-gin

前置 gin是go的一个web框架&#xff0c;我们简单介绍一下gin的使用 导入gin &#xff1a;"github.com/gin-gonic/gin" 我们使用import导入gin的包 简单示例&#xff1a; package mainimport ("github.com/gin-gonic/gin" )func main() {r : gin.Default(…

C# NX二次开发:判断两个体是否干涉和获取系统日志的UFUN函数

大家好&#xff0c;今天要讲关于如何判断两个体是否干涉和获取系统日志的UFUN函数。 &#xff08;1&#xff09;UF_MODL_check_interference&#xff1a;这个函数的定义为根据单个目标体检查每个指定的工具体是否有干扰。 Defined in: uf_modl.h Overview Checks each sp…

如何解决 Linux 系统文件描述符耗尽的问题

在Linux系统中&#xff0c;文件描述符&#xff08;File Descriptor, FD&#xff09;是操作系统管理打开文件、套接字、管道等资源的抽象标识。当进程或系统耗尽文件描述符时&#xff0c;会导致服务崩溃、连接失败等严重问题。以下是详细的排查和解决方案&#xff1a; --- ###…

LVGL简易计算器实战

文章目录 &#x1f4c1; 文件结构建议&#x1f539; eval.h 表达式求值头文件&#x1f539; eval.c 表达式求值实现文件&#xff08;带详细注释&#xff09;&#x1f539; ui.h 界面头文件&#x1f539; ui.c 界面实现文件&#x1f539; main.c 主函数入口✅ 总结 项目效果&…

使用countDownLatch导致的线程安全问题,线程不安全的List-ArrayList,线程安全的List-CopyOnWriteArrayList

示例代码 package com.example.demo.service;import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class UnSafeCDTest {Executor…

ALLinSSL:一站式SSL证书管理解决方案

引言 在当今互联网安全日益重要的背景下,SSL证书已成为保护网站安全的必备工具。然而,管理多个SSL证书常常是一项繁琐且容易出错的任务。ALLinSSL应运而生,它提供了一个一站式的SSL证书管理解决方案,大大简化了证书的申请、安装和更新过程。本文将深入介绍ALLinSSL的特性、…

嵌入式通信协议总览篇:万物互联的基石

嵌入式系统的世界,是靠协议“说话”的世界。 在你设计一个智能设备、构建一个工业控制系统、开发一款 IoT 网关时,一个核心问题始终绕不开:**这些设备之间如何“对话”?**答案就是——通信协议。 本篇作为系列第一章,将带你全面理解嵌入式通信协议的全貌,为后续深入学习…

【数据结构】红黑树(C++)

目录 一、红黑树的概念 二、红黑树的性质 三、红黑树结点定义 四、红黑树的操作 1. 插入操作 1.1 插入过程 1.2 调整过程 1.2.1 叔叔节点存在且为红色 1.2.2 叔叔节点存在且为黑色 1.2.3 叔叔节点不存在 2. 查找操作 2.1 查找逻辑 2.2 算法流程图 2.3 使用示例 …

Oracle数据库DBF文件收缩

这两天新部署了一套系统&#xff0c;数据库结构保持不变&#xff0c;牵扯导出表结构还有函数&#xff0c;图省事就直接新建用户&#xff0c;还原数据库了。然后咔咔咔&#xff0c;一顿删除delete&#xff0c;truncate&#xff0c;发现要不就是表删了&#xff0c;还有num_rows&a…

【字节拥抱开源】字节豆包团队开源首发 Seed-Coder 大模型

我们非常高兴地向大家介绍 Seed-Coder&#xff0c;它是一个功能强大、透明、参数高效的 8B 级开源代码模型系列&#xff0c;包括基础变体、指导变体和推理变体。Seed-Coder 通过以下亮点促进开放代码模型的发展。 以模型为中心&#xff1a;Seed-Coder主要利用大语言模型&#…

Qt 无边框窗口,支持贴边分屏

常规操作, 无法进行窗口的大小缩放和移动贴边分屏等操作 // 去掉标题栏,去掉工具栏&#xff0c;窗口置顶 setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);重点介绍 QWindowKit https://github.com/stdware/qwindowkit 跨平台的支持Windows\…

Qt 样式表:全面解析与应用指南

在 Qt 开发中,样式表(Style Sheets)是定义应用程序界面外观的关键工具。它采用文本格式的规则集合,借鉴了 CSS 语法,借助选择器、属性和值,能精准把控各类控件的外观表现,极大提升了界面设计的灵活性与美观性。 文章目录 一、样式可更改的效果​1、颜色相关效果​2、字体…

追踪大型语言模型的思想(上)(来自针对Claude的分析)

概述 像 Claude 这样的语言模型并非由人类直接编程&#xff0c;而是通过大量数据进行训练。在训练过程中&#xff0c;它们会学习解决问题的策略。这些策略被编码在模型为每个单词执行的数十亿次计算中。对于我们这些模型开发者来说&#xff0c;这些策略是难以捉摸的。这意…

Python pandas 向excel追加数据,不覆盖之前的数据

最近突然看了一下pandas向excel追加数据的方法&#xff0c;发现有很多人出了一些馊主意&#xff1b; 比如用concat,append等方法&#xff0c;这种方法的会先将旧数据df_1读取到内存&#xff0c;再把新数据df_2与旧的合并&#xff0c;形成df_new,再覆盖写入&#xff0c;消耗和速…