使用Apache RewriteRule相对URL时301重定向自动加端口的解决办法
解决Apache RewriteRule重定向自动带端口的问题
这个问题我之前维护多站点配置时也碰到过——Apache在处理相对URL的301重定向时,会默认把当前请求的端口(比如你的81)拼到最终的重定向URL里,刚好踩中了你多站点不能硬编码域名的痛点。给你两个不用固定域名就能解决的方案:
方案1:利用请求Host头构造不带端口的绝对URL
通过正则捕获请求Host头里不带端口的部分,再拼接成绝对URL,这样既能保留原站点的域名(不管是.com还是.ca),又能去掉端口:
RewriteCond %{HTTP_HOST} ^(.*?)(:\d+)?$ RewriteRule ^/foo http://%1/somedirectory/foo [NC,L,R=301]
%{HTTP_HOST}:获取请求里的Host头(比如www.foo.com:81或www.foo.ca)- 正则
^(.*?)(:\d+)?$:捕获Host头里不带端口的核心域名部分(也就是%1变量) - 最终生成的重定向URL会自动适配原站点域名,且不会包含端口
方案2:用VirtualHost配置的ServerName生成重定向URL
如果你的两个站点已经在VirtualHost里正确配置了ServerName(比如www.foo.com和www.foo.ca),直接用%{SERVER_NAME}变量更可靠——这个变量是配置文件里固定的域名,不会被请求的Host头篡改:
RewriteRule ^/foo http://%{SERVER_NAME}/somedirectory/foo [NC,L,R=301]
每个VirtualHost的SERVER_NAME不同,重定向时会自动使用对应站点的域名,同样不会带端口。
为什么原来的配置会带端口?
当你用/somedirectory/foo这种相对路径做R=301重定向时,Apache会自动拼接当前请求的协议+主机+端口生成完整的重定向URL。如果你的请求是通过端口81进来的,自然就会把81带上。换成用变量构造的绝对URL,就能手动控制不包含端口部分。
内容的提问来源于stack exchange,提问作者TheKiltedKimchi
相关产品推荐
相关产品推荐

