必须用 VirtualHost 拦截 IP 访问:在 httpd-vhosts.conf 顶部配置 ServerName 为实际 IP 的拒绝型 VirtualHost,再配真实域名的允许型 VirtualHost,确保 Include 行启用且无 NameVirtualHost 指令。

直接结论:必须用 VirtualHost 捕获默认请求,不能靠 Require all granted 或 .htaccess 解决——后者只管权限,不管路由匹配。
为什么直接访问 IP 会进到默认站点?
Apache 启动后,只要有一个 VirtualHost *:80 存在,且没显式声明 ServerName 匹配当前请求的 Host 头,它就会被当作“默认虚拟主机”兜底。你没配域名时输 http://192.168.1.100,Host 头就是那个 IP 字符串,Apache 找不到精确匹配,就扔给第一个或标记为 default 的 VirtualHost ——于是你的网站照常打开,完全没拦住。
配置两个 VirtualHost 拦截 IP 访问
核心思路是:让 IP 请求命中一个“空”或“拒绝型”的虚拟主机,而把合法域名交给另一个。顺序和 ServerName 值必须严格对应:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 在
httpd-vhosts.conf最顶部添加第一个VirtualHost,ServerName设为你服务器的公网/局域网 IP(如192.168.1.100),DocumentRoot指向一个空目录(如C:/xampp/htdocs/denied),并在其<directory></directory>块中写Require all denied - 第二个
VirtualHost写你的真实域名,比如ServerName mysite.local,DocumentRoot指向真实项目路径,Require all granted - 确保两个
VirtualHost都监听*:80,且没有遗漏Listen 80(已在httpd.conf中启用) - 重启 Apache,再用浏览器访问
http://192.168.1.100,应返回 403;访问http://mysite.local则正常
ServerName 写 IP 还是域名?
必须写实际 IP 地址(不是 127.0.0.1,除非你只在本机测试),否则无法匹配 Host 头。常见错误包括:
- 写成
ServerName localhost—— 浏览器访问 IP 时 Host 头不是localhost,不匹配 - 写成
ServerName _或留空 —— Apache 会忽略该字段,退化为默认匹配 - IP 地址带端口(如
192.168.1.100:80)——ServerName不接受端口,会解析失败 - 没在系统 hosts 文件里加
127.0.0.1 mysite.local—— 域名根本解析不了,压根进不了第二个VirtualHost
别碰 httpd.conf 里的 NameVirtualHost
Apache 2.4+ 已废弃 NameVirtualHost 指令,XAMPP 自带版本(通常 2.4.52+)如果还保留这行,反而可能引发警告甚至启动失败。检查 httpd.conf,确认已注释或删除所有 NameVirtualHost 行。真正起作用的是 VirtualHost 块自身的 ServerName 和监听地址组合。
最容易被忽略的一点:改完 httpd-vhosts.conf 后,必须确保 httpd.conf 中这一行没被注释:Include "conf/extra/httpd-vhosts.conf"。漏掉这句,所有虚拟主机配置都不生效,IP 访问依然直通默认站点。

















