如上。
最好用一个例子来解释:
原始 URL(参数顺序不一致)
如果我访问上述 3 个示例 URL 中的任何一个,我希望被重定向到www.myhost.com/my-page/v1/v2
- p3 被故意忽略,因为不再需要它。
- 在我的实际 URL 中,我有 p4 到 p6 参数,这些参数也被忽略了。为了简单起见,我只写了 p3 参数。
我在网上搜索过,但没有找到我想要的东西。谢谢。
答案1
你可以使用 mod_rewrite 按照如下方式进行操作:
RewriteEngine On
RewriteCond %{QUERY_STRING} (?:^|&)p1=([^&]+)
RewriteCond %1@%{QUERY_STRING} ^([^@]+)@(?:|.*&)p2=([^&]*)
RewriteRule ^/?(my-page)$ /$1/%1/%2 [QSD,R=302,L]
首先状况捕获的值p1
并将其传递给第二个状况还捕获了 的值p2
。然后将它们用于代换分别将字符串作为%1
和%2
反向引用。
URL 参数可以按任意顺序出现。
@
(在第二种条件中)只是一个不会出现在和中的任意字符v1
,因此在搜索时用作v1
和查询字符串之间的分隔符p2
。
所有其他 URL 参数(即p3
... pN
)都被忽略(并丢弃)。
p1
要进行重定向,和必须都p2
存在且具有非空值。
更新: p1
必须存在且值非空(否则生成的重定向将不明确)。p2
也必须存在,但值可以是空的。我还更新了正则表达式,以便它还可以允许格式错误(但仍然有效)的查询字符串,其中 URL 参数分隔符(&
)出现p2
在查询字符串的最开始之前。例如,/my-page?&p2=&p1=v1
仍然会被重定向到/my-page/v1/
。
该QSD
标志丢弃请求中的原始查询字符串。
取决于这些指令的使用地点(例如目录或者服务器上下文)以及 URL 最终如何路由,您可能需要添加初始条件以确保只处理直接请求(而不是重写的请求)。
例如,如果需要,添加以下内容作为第一个条件:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
:
更新:
p1 和 p2 是强制性的。p3 是可选的。
您可以按如下方式更改上述内容:
RewriteCond %{QUERY_STRING} (?:^|&)p1=([^&]+)
RewriteCond %1@%{QUERY_STRING} ^([^@]+)@(?:|.*&)p2=([^&]+)
# Either p3 is mandatory and must have a value
RewriteCond %1/%2/@%{QUERY_STRING} ^([^@]+)@(?:|.*&)p3=([^&]+) [OR]
# OR p3 is omitted or does not have a value
RewriteCond %1/%2 (.+)
RewriteRule ^/?(my-page)$ /$1/%1%2 [QSD,R,L]
第二个条件现在确保参数有一个值p2
(即v2
) - 它不能为空。
p3
然后第三个条件检查参数是否为非空或者p3
第四个条件只是捕获参数为空或完全省略时的值。
p3
当不存在时,生成的重定向会省略尾部斜杠。例如,生成的重定向是/mypage/v1/v2
或。(避免/mypage/v1/v2/v3
了可能出现在 上的尾部斜杠。)/mypage/v1/v2/
在决赛中代换%1
字符串,和反向引用的值%2
与之前略有不同。它们不再包含每个值(即v1
和v2
)。而是%1
包含v1/v2
和%2
包含/v3
(包括斜杠前缀)或空的(当p3
为空或省略时)。