在 Apache 服务器上,我需要将 mydomain.com/something/?p=value 重写为 mydomain.com/something/?page=value
我试过:
RewriteEngine On
RewriteCond %{QUERY_STRING} p=(.*)
RewriteRule ^(.*)/p=$ $1?page=%{QUERY_STRING} [L,QSA]
但不要炒菜,可以帮帮我吗?
答案1
RewriteCond %{QUERY_STRING} p=(.*) RewriteRule ^(.*)/p=$ $1?page=%{QUERY_STRING} [L,QSA]
这里有很多“错误”:
这
RewriteRule
图案,即^(.*)/p=$
,永远不会匹配,因为p=
不作为 URL 路径的一部分出现(它是查询字符串的一部分)。RewriteRule
图案仅匹配 URL 路径,特别排除查询字符串。因此,上述操作对所述示例 URL 不起作用。您正在使用服务器
QUERY_STRING
变量代替value
代换字符串。但QUERY_STRING
显然是整个“查询字符串”,因此最终会构造出以下形式的错误查询字符串:page=p=<value>
。使用该
QSA
标志会导致请求中的原始查询字符串合并使用您在中使用的查询字符串代换字符串。因此,这将导致&p=<value>
被附加,而这并不是您所需的。您正在寻找替换现有查询字符串的方法。RewriteRule ^(.*)/p=$ $1?page=
- 您正在从捕获组中排除尾部斜杠RewriteRule
图案,因此这将有效地从重写的 URL 中删除尾部斜杠。这与您的示例不同。你似乎需要内部重写(不外部重定向),而您“仅”更改了单个 URL 参数的名称。这通常是您在应用程序中解析的内容,而不是 Apache 中的 URL 重写。(?)
请尝试以下操作:
RewriteEngine On
# Internally "rewrite" the request
RewriteCond %{QUERY_STRING} ^p=([^&]*)$
RewriteRule (.*/)$ $1?page=%1 [L]
这会匹配任何以斜杠结尾的 URL 路径(如您的示例所示)。%1
反向引用指的是最后匹配的捕获组条件模式,即 URL 参数的值p
。假设 是p=<value>
请求中唯一的 URL 参数。
更新:似乎不起作用...如果我打电话,
localhost/list/?p=2
我只是得到localhost/list/?p=2
是的,可见的 URL 不会改变,因为这是一个内部的“重写”(正如您在问题中要求的那样)。 URL 是内部重写为list/?page=2
。(还有一个点list/?page=2
严格来说不是一个有效的端点 - 它需要进一步重写,也许通过 mod_dir 来形成有效的请求。例如list/index.php?page=2
?)
如果你希望 URL 明显改变,那么你可能需要外部的毕竟是“重定向”?为此,您需要在RewriteRule
代换字符串并添加R
( redirect
) 标志。例如:
# Externally "redirect" the request
RewriteCond %{QUERY_STRING} ^p=([^&]*)$
RewriteRule (.*/)$ /$1?page=%1 [R=302,L]
如果我修改规则得到
localhost/list/?p=2&?p=2
如下结果:RewriteEngine On RewriteCond %{QUERY_STRING} ^p=([^&]*)$ RewriteRule (.*/)$ $1&?page=%1 [L]
/list/&
我得到“在此服务器上找不到请求的 URL 。”作为“?” 削减重写
如果您请求localhost/list/?p=2&?p=2
(但为什么?),那么上述指令将不会执行任何操作,因为条件不匹配。
为什么&
在RewriteRule
代换字符串?(这没有意义?)/list/&
如果处理了规则,这确实会产生形式为 的 URL 路径。但如上所述,它不会针对您所述的 URL 进行处理?