Apache子目录Mod_Rewrite规则被父目录规则拦截,API端点请求异常
Apache子目录Mod_Rewrite规则被父目录规则拦截,API端点请求异常
看起来问题的核心是父目录public的Rewrite规则优先级高于子目录api的规则:当请求/api/v1.0/some-endpoint这类不存在物理文件的路径时,父目录的规则先触发,把请求转到了父级的index.php,最终返回404错误。而访问/api/本身正常,是因为这个物理目录存在,父规则里的RewriteCond %{REQUEST_FILENAME} -d会匹配到,直接跳过后续Rewrite规则,交给子目录的规则处理。
下面是具体的修复方案,分两步调整你的Apache配置:
第一步:修改父目录public的Rewrite规则,排除API路径
在public目录的Rewrite规则中,添加一个条件,让父规则不处理以/api/开头的请求,这样这些请求会自动落到子目录api的规则里。修改后的配置如下:
<Directory /path/to/app/public> RewriteEngine On RewriteBase / # 新增:排除API子目录的请求,交给/api的规则处理 RewriteCond %{REQUEST_URI} !^/api/ [NC] RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^.*\.(media.php|png|jpg|gif|ico)$ media.php [NC,L] RewriteRule ^.*\.(xml|txt|css|js)$ static.php [NC,L] # 仅处理非API的请求 RewriteRule ^.*$ index.php/ [NC,L] errordocument 404 /error.php?id=404 </Directory>
第二步:优化API子目录的Rewrite规则
确保API目录的规则能正确接收并传递请求路径到index.php,同时明确开启RewriteEngine(避免继承问题):
<Directory /path/to/app/public/api> RewriteEngine On RewriteBase /api/ Header set Access-Control-Allow-Methods "PUT, GET, POST, DELETE, HEAD, OPTIONS" RewriteCond %{HTTP:Authorization} ^(.*) RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] # 将请求的URI路径传递给index.php,比如/api/v1.0/some-endpoint会转为index.php?v1.0/some-endpoint RewriteRule ^(.*)$ index.php?$1 [L,NC] </Directory>
为什么这样改?
- 父目录排除规则:通过
RewriteCond %{REQUEST_URI} !^/api/,告诉Apache所有以/api/开头的请求不要走父目录的Rewrite逻辑,直接交给子目录的规则处理。 - API子目录规则优化:设置
RewriteBase /api/确保路径解析正确,RewriteRule ^(.*)$ index.php?$1把请求的具体端点路径(比如v1.0/some-endpoint)作为参数传递给API的index.php,这样你的API程序就能正确识别端点了。
额外验证步骤
- 重启Apache服务,让配置生效:
sudo systemctl restart apache2(根据你的系统调整命令) - 确认
mod_rewrite模块已启用:执行apachectl -M | grep rewrite,如果输出rewrite_module (shared)说明已启用 - 测试
/api/v1.0/some-endpoint请求,看是否能被API的index.php正确处理
备注:内容来源于stack exchange,提问作者oucil
相关产品推荐
相关产品推荐

