Ubuntu16.04+Apache环境下子域名带路径跳转主域名匹配路径失效问题
问题根因排查与修复方案
1. 确认虚拟主机配置正确
你当前的虚拟主机只绑定了主域名和www域名,即使加了单条子域名别名,也没法覆盖所有可能的子域名请求,直接修改虚拟主机的ServerAlias配置为通配符形式,确保所有子域名请求都会进入该虚拟主机处理:
<VirtualHost *:80> ServerAdmin webmaster@example.com DocumentRoot /var/www/example.com/public_html ServerName example.com # 替换原有单个别名,用通配符匹配所有子域名 ServerAlias www.example.com *.example.com <Directory /var/www/example.com/public_html/> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> # 其余原有配置保持不变 </VirtualHost>
修改后执行systemctl restart apache2重启服务生效。
如果你的站点已经开启HTTPS,务必在443端口的虚拟主机配置中也做相同修改,否则HTTPS的子域名请求不会匹配到跳转规则。
2. 修正Rewrite规则的位置与语法
你遇到的带路径不跳转的问题,90%以上是规则位置或者语法匹配问题:
情况A:规则写在.htaccess文件中
一定要把跳转规则放在WordPress自动生成的Rewrite规则之前,WordPress的默认规则带有[L]标记,匹配到请求后就不会执行后续规则,导致子域名带路径的请求被WordPress拦截处理,无法触发跳转。
完整的.htaccess开头规则如下:
RewriteEngine On # 匹配所有非主域名、非www域名的子域名请求 RewriteCond %{HTTP_HOST} !^example\.com$ [NC] RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC] RewriteRule ^(.*)$ https://example.com/$1 [R=302,L,NC] # 下面是WordPress原有默认规则,不要修改
测试跳转正常后,再把R=302改成R=301(301是永久跳转,浏览器会长期缓存,测试阶段用临时跳转避免缓存影响结果)。
情况B:规则写在虚拟主机.conf文件中
如果你的规则直接写在<VirtualHost>段下,而非<Directory>段内,那么请求路径默认带前导斜杠,你原有规则的^(.*)$无法匹配/page1这类带前缀斜杠的路径,需要修改规则为:
RewriteEngine On RewriteCond %{HTTP_HOST} !^example\.com$ [NC] RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC] RewriteRule ^/(.*)$ https://example.com/$1 [R=302,L,NC]
3. 通用排查步骤
如果修改后仍未生效,按以下顺序排查:
- 清除浏览器缓存或者用无痕模式测试,避免旧的301跳转缓存干扰
- 执行
a2enmod rewrite确认rewrite模块已经开启,重启Apache生效 - 开启Rewrite调试日志,在虚拟主机配置中添加
LogLevel alert rewrite:trace3,重启后查看/var/log/apache2/error.log即可看到完整的规则匹配过程,快速定位未匹配的原因
内容的提问来源于stack exchange,提问作者user16421
相关产品推荐
相关产品推荐

