Apache URL重写与代理配置失败:请求返回404 Not Found
Apache URL重写与代理配置问题排查与解决
问题根源
Apache中ProxyPass指令的执行优先级高于mod_rewrite规则,请求到达时会直接被ProxyPass转发到后端8080服务,此时RewriteRule还未执行,后端因不存在/oldcontext/路径返回404。另外,原重写规则未处理请求参数中的双引号("),即使规则生效,传递给后端的accnum参数会包含多余引号,不符合第三方应用要求。
修复方案
方案一:用mod_rewrite的P flag实现代理(推荐)
移除ProxyPass和ProxyPassReverse,改用mod_rewrite的P flag直接完成重写+代理,确保规则优先执行:
<VirtualHost *:80> RewriteEngine on # 匹配带双引号的acc参数,提取纯数字账号 RewriteCond %{QUERY_STRING} acc="([0-9]+)" # 重写路径并代理到后端,P表示代理,L表示终止后续规则 RewriteRule ^oldcontext/$ http://127.0.0.1:8080/?accnum=%1 [P,L] # 其他路径正常代理到后端 RewriteRule ^(.*)$ http://127.0.0.1:8080/$1 [P,L] RequestHeader unset Origin ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
方案二:保留ProxyPass,排除oldcontext路径
通过ProxyPassMatch排除/oldcontext/路径,让mod_rewrite先处理该路径请求,再转发到后端:
<VirtualHost *:80> RewriteEngine on RewriteCond %{QUERY_STRING} acc="([0-9]+)" # 内部重写路径,不触发客户端重定向(移除R=301) RewriteRule ^oldcontext/$ /?accnum=%1 [L] # 排除oldcontext路径,其余路径正常代理 ProxyPassMatch ^/(?!oldcontext/) http://127.0.0.1:8080/ ProxyPassReverse / http://127.0.0.1:8080/ RequestHeader unset Origin ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
关键说明
- 正则调整:
acc="([0-9]+)"精准匹配带双引号的账号参数,只提取数字部分,保证传递给后端的accnum是纯账号数字。 - 移除
R=301:如果不需要客户端可见URL变化,使用内部重写(无R flag)或代理(P flag);R=301会触发客户端重定向,暴露后端URL结构。 - 模块验证:你已通过
a2enmod启用rewrite、headers、proxy、proxy_http模块,此部分无需额外操作。
内容的提问来源于stack exchange,提问作者Yogesh Devi
相关产品推荐
相关产品推荐

