.htaccess中RewriteRule无法匹配带问号的URL重写问题
嘿,我来帮你搞定这个URL重写的问题!你遇到的其实是mod_rewrite里一个超常见的误区——RewriteRule的匹配范围不包含URL里的查询字符串(也就是?后面的参数部分),它只负责匹配域名之后、?之前的路径内容,比如这里的/index.php。
你之前写的规则不管有没有转义?,都没法生效,因为你试图让RewriteRule去匹配它管不到的查询字符串部分,这完全找错了对象😂
给你一套能正常工作的规则,分两部分实现需求:
# 1. 把旧的带参数URL永久重定向到新的美观URL RewriteCond %{REQUEST_URI} ^/index\.php$ RewriteCond %{QUERY_STRING} ^gid=([^&]+)&u=([^&]+)&id=([^&]+)$ RewriteRule ^(.*)$ /login/%1/%2/%3? [R=301,L] # 2. 让新URL内部重写到原来的index.php处理请求(浏览器地址栏保持新URL) RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^login/([^/]+)/([^/]+)/([^/]+)$ /index.php?gid=$1&u=$2&id=$3 [L]
我给你拆解下每个部分的作用:
第一组规则是处理旧URL跳转到新URL:
- 第一条
RewriteCond确保请求的是index.php文件; - 第二条
RewriteCond专门匹配查询字符串,用[^&]+精准捕获每个参数的值(比你之前用的.*更安全,不会意外匹配到后面的&符号); RewriteRule里的%1、%2、%3对应上面捕获到的三个参数值,末尾的?是用来清空新URL的查询字符串,避免旧参数带过去;R=301是永久重定向,告诉搜索引擎更新索引,L表示这是当前匹配的最后一条规则。
- 第一条
第二组规则是处理新URL的内部逻辑:
- 先检查请求的不是实际存在的文件或目录(避免影响你的静态资源比如图片、CSS);
- 捕获新URL里的三个分段,把它们作为参数传递给
index.php,这个过程是服务器内部处理的,浏览器地址栏会一直显示美观的新URL。
要是你只需要旧URL跳转到新URL(不需要反向处理),那只保留第一组规则就行。
内容的提问来源于stack exchange,提问作者bcanata
相关产品推荐
相关产品推荐

