使用mod_rewrite替换查询字符串参数值

6

I would like to map this:

http://www.example.com/index.php?param1=value1&param2=value2&param3=value3 (etc. ad infinitum)

为了

http://www.example.com/index.php?param1=newvalue1&param2=value2&param3=value3 (etc.)

换句话说,只需更改查询字符串中单个参数的值。我知道旧值是什么,所以我正在尝试匹配精确文本index.php?param1=value1并将其替换为index.php?param1=newvalue1。我似乎找不到任何使用mod_rewrite执行此操作的示例。非常感谢您的任何帮助。
2个回答

7
尝试使用这个规则:
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)param1=value1(&.*)?$
RewriteRule ^index\.php$ /index.php?%1param1=newvalue1%3 [L,R=301]

实际上,仍然存在一个小问题 - 尽管在那里加上 [R=301] 可以工作,但是如果我把它拿掉(试图进行透明重定向),它就不再工作了 - 规则似乎被完全忽略了。 - Russ
顺便提一下,我可能还想在这个重定向期间保留任何POST值。我知道使用mod_rewrite重定向到内部页面应该会保留POST数据,但在这种情况下它不起作用,只有GET数据在重定向后出现。 - Russ
这正是我所想的,但如果没有R标志,整个事情就会被忽略。一旦我重新加入R标志,它就能再次工作,但我会失去POST数据。我不能使用PHP,因为这一切都发生在我无法控制的CMS上下文中。 - Russ
@Ross:L标志只是结束当前的处理。但它也会重新注入请求并导致从第一条规则开始重复处理(请参见http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteflags)。`P`标志是使用代理来请求重写后的URL并将响应传回给客户端。这确实需要mod_proxy。 - Gumbo
需要注意的是,如果查询值中包含 &,可能会出现问题。 - John Kurlak
显示剩余11条评论

2
这种解决方案比较脆弱,因为它依赖于GET参数的顺序,但对于你的特定示例来说是有效的,可以保留param1后的任何GET参数,并保留POST参数。
RewriteCond %{QUERY_STRING} param1=value1(&.*)*$
RewriteRule ^/index\.php$ /index.php?param1=newvalue1%1 [L]

我有一个小的测试php页面,只需要执行print_r($_GET)print_r($_POST),使用curl从命令行发送post参数,我看到以下内容:

$ curl --data "post1=postval1&post2=postval2" "http://www.example.com/index.php?param1=value1&param2=value2&param3=value3"
_GET
Array
(
    [param1] => newvalue1
    [param2] => value2
    [param3] => value3
)

_POST
Array
(
    [post1] => postval1
    [post2] => postval2
)

如果您想使重写条件更灵活,可以添加一些条件模式,就像Gumbo所做的那样,但最好知道您需要处理哪些条件(即param1可以在任何位置吗?可以是唯一的get参数等等)。
下面的内容似乎适用于在查询字符串或URL中的任何位置替换"value1"为"newvalue1"(但不适用于发布的键/值)。
RewriteCond %{QUERY_STRING} ^(.*)value1(.*)$
RewriteRule ^(.*)$ $1?%1newvalue1%2 [L]

RewriteRule ^(.*)value1(.*)$ $1newvalue1$2 [L]

%N 用于替换 RewriteCond 中的值,而 $N 用于替换 RewriteRule 本身中的值。你只需要使用两个 RewriteRules,其中一个带有关联的 RewriteCond 来处理查询字符串。


实际上,需求有点变化 - 现在我只想用另一个文本字符串替换一个文本字符串。该字符串可能出现在URL的任何位置(即在查询字符串中或作为路径的一部分)。所以我想要更改:http://www.mydomain.com/string1/string2/string3到http://www.mydomain.com/string1/new_string2/string3以及http://www.mydomain.com/index.php?string1=value1&string2=value2&string3=value3http://www.mydomain.com/index.php?string1=value1&new_string2=value2&string3=value3 - Russ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接