.htaccess重写URL结构失败,外部重定向出现500错误求助
URL重写配置修复方案
问题描述
网站需要将photo?title=SOME-URL格式的URL转换为photo/SOME-URL形式,但现有.htaccess配置无法生效,且外部重定向返回500内部服务器错误。原配置如下:
Options +FollowSymLinks -MultiViews # Turn mod_rewrite on RewriteEngine On RewriteBase / # This sets my public folder as main directory RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteCond %{REQUEST_URI} !^/public/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /public/$1 RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteRule ^(/)?$ public/index.php [L] # To remove the query title and introduce looks RewriteCond %{THE_REQUEST} \s/+photo(?:\.php)?\?title=([A-Za-z0-9\-\_]+) [NC] RewriteRule ^ photo/%1? [R,L] RewriteRule ^photo/([A-Za-z0-9\-\_]+)/?$ photo.php?title=$1 [NC,L] # To externally redirect /dir/file.php to /dir/file RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC] RewriteRule ^ %1 [R=302,L] # To internally forward /dir/file to /dir/file.php RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^(.*?)/?$ $1.php [L]
问题原因
- 规则顺序错误:
public目录转发规则未加[L]标记,导致请求会继续匹配后续规则,引发循环,最终触发500错误。 - 路径适配缺失:后续的
photo重写规则基于根目录,但实际请求已被转发到public目录,路径不匹配导致规则失效。 - 无后缀URL重写未适配
public结构:原规则无法正确映射到public目录下的.php文件。
修复后的配置
调整规则顺序,添加终止标记,适配public目录结构:
Options +FollowSymLinks -MultiViews # Turn mod_rewrite on RewriteEngine On RewriteBase / # 优先处理旧URL的外部重定向,避免进入public后无法匹配 RewriteCond %{THE_REQUEST} \s/+photo(?:\.php)?\?title=([A-Za-z0-9\-\_]+) [NC] RewriteRule ^ photo/%1? [R=302,L] # 将请求转发到public目录,添加L标记终止后续规则匹配 RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ RewriteCond %{REQUEST_URI} !^/public/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /public/$1 [L] # 处理根目录请求 RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ RewriteRule ^(/)?$ public/index.php [L] # 内部转发photo/SOME-URL到public/photo.php?title=SOME-URL RewriteRule ^photo/([A-Za-z0-9\-\_]+)/?$ public/photo.php?title=$1 [NC,L] # 外部重定向public下的.php后缀URL到根目录无后缀形式 RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+public/([^.]+)\.php [NC] RewriteRule ^public/%1 /%1 [R=302,L] # 内部转发无后缀URL到public目录下的对应.php文件 RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{DOCUMENT_ROOT}/public/$1.php -f RewriteRule ^(.*?)/?$ public/$1.php [L]
关键调整说明
- 前置旧URL重定向:先处理
photo?title=xxx到photo/xxx的跳转,避免请求进入public后无法匹配原始规则。 - 添加
[L]终止标记:给public目录转发规则加上[L],防止规则循环触发500错误。 - 适配
public路径:所有内部转发规则的目标路径添加public/前缀,确保文件查找正确;外部重定向规则匹配public下的.php文件,生成根目录下的无后缀URL。
内容的提问来源于stack exchange,提问作者Aleksandrius
相关产品推荐
相关产品推荐

