这应该很简单,但我遇到了很多麻烦。
目标: 如果“名称”查询参数有尾随冒号,将其删除:
https://example.com/dir/?foo=bar&name=hello:&baz=bat#123 ==>
https://example.com/dir/?foo=bar&name=hello&baz=bat#123
我已经尝试了一堆规则,但没有找到有效的规则。我最接近的是:
# Grab "name" value w/out trailing colon
RewriteCond %{QUERY_STRING} (.*[?&]*)name=(.*):(.*)
# Duplicate original path and add query parameters
RewriteRule ^(.*)$ /$1?%1name=%2%3 [L,R=302]
这几乎可以工作,除了它重定向到顶级目录:
https://example.com/dir/?foo=bar&name=hello:&baz=bat#123 ==>
https://example.com/?foo=bar&name=hello&baz=bat#123
我希望此重写适用于顶级域名或任何数量的子目录。我怎样才能做到这一点?谢谢!
(.*[?&]*)name=(.*):(.*)
此正则表达式不仅匹配
name
URL 参数值末尾的尾随冒号,它匹配 name=
后跟 :
查询字符串中的任何位置(包括在其他 URL 的中间或作为其他 URL 的一部分参数)。它还匹配任何仅以 name
结尾的 URL 参数名称,例如。 fooname=hello&bar=ba:z
.
缺少的子目录似乎表明您在
.htaccess
子目录(相对于根目录)中的 /dir
文件中使用此规则? RewriteRule
pattern(您正在捕获)仅匹配相对于包含 .htaccess
文件的目录的 URL 路径。
请注意,片段标识符(
#123
部分)不会发送到服务器 - 这完全由浏览器管理。
根据您期望的 URL 参数值,您可能需要
NE
指令上的 noescape
(RewriteRule
) 标志,以防止结果值在重定向响应中被双重 URL 编码。这是因为 QUERY_STRING
服务器变量未经过 % 解码,生成的替换字符串在发送回客户端之前默认经过 % 编码。
请尝试以下操作:
# Grab "name" value w/out trailing colon
RewriteCond %{QUERY_STRING} ^(.+&)?(name=[^&]*):(&.+)?$
# Duplicate original path and add query parameters
RewriteRule ^ %{REQUEST_URI}?%1%2%3 [NE,R=302,L]
我在捕获子模式中包含了
name=
部分。 name
URL 参数之前或之后的任何 URL 参数都是完全可选的。仅删除 name
URL 参数值末尾的冒号。
REQUEST_URI
服务器变量包含根目录相对 URL 路径,因此无论 .htaccess
文件位于何处,这都可以保留 URL 路径。