如何在Laravel中用.htaccess实现带相同查询字符串的域名重定向
解决Laravel+Angular项目.htaccess域名重定向丢失路径的问题
问题场景
项目前端基于Angular、后端基于Laravel,需要实现域名连同路径(含查询字符串)重定向到新域名,但现有.htaccess配置未保留原路径,所有请求都被重定向到新域名的index.php页面:
- 期望效果:
xxx.com/this-is/the-path?foo=bar→yyy.com/this-is/the-path?foo=bar - 实际效果:
xxx.com/this-is/the-path?foo=bar→yyy.com/index.php
原配置代码:
<IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews </IfModule> RewriteEngine On # Redirect Trailing Slashes If Not A Folder... RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1 [L,R=301] # Handle Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] # Handle Authorization Header RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] </IfModule> # -- REDIRECTION to https (optional): # If you need this, uncomment the next two commands # RewriteCond %{HTTPS} !on # RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} # -- # CustomRedirect start RewriteCond %{HTTP_HOST} ^xxx.io$ [OR] RewriteCond %{HTTP_HOST} ^yyy.lt$ RewriteRule ^(.*)$ https://test.lt/$1 [L,QSA,R=302] # CustomRedirect end RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^(.*) index.html [NC,L]
问题原因
原配置中,Laravel的前端控制器规则(RewriteRule ^ index.php [L])优先级高于自定义重定向规则,所有非文件/目录的请求会先被转发到index.php,之后执行重定向时,路径已经被替换成index.php,导致原路径丢失。
解决方案
将自定义重定向规则移到Laravel的Rewrite规则之前,确保重定向逻辑先触发,不会被前端控制器拦截。
修改后的完整.htaccess配置:
<IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews </IfModule> RewriteEngine On # CustomRedirect start - 移到最前面,优先执行重定向 RewriteCond %{HTTP_HOST} ^xxx.io$ [OR] RewriteCond %{HTTP_HOST} ^yyy.lt$ RewriteRule ^(.*)$ https://test.lt/$1 [L,QSA,R=302] # CustomRedirect end # Redirect Trailing Slashes If Not A Folder... RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1 [L,R=301] # Handle Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] # Handle Authorization Header RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] </IfModule> # -- REDIRECTION to https (optional): # If you need this, uncomment the next two commands # RewriteCond %{HTTPS} !on # RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} # -- RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^(.*) index.html [NC,L]
关键说明
- 重定向规则优先级:将自定义重定向放在Laravel规则之前,确保匹配到目标域名的请求直接跳转,不会进入Laravel的前端控制器流程。
- QSA标记:
QSA(Query String Append)会自动将原请求的查询字符串附加到新URL后,保证参数不丢失。 - L标记:
L表示这是最后一条匹配的规则,避免后续规则干扰重定向逻辑。
内容的提问来源于stack exchange,提问作者AbdulSamet Şahin
相关产品推荐
相关产品推荐

