我写了以下重写规则:
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} rp=\/knowledgebase\/.*
RewriteRule ^\/customer\/index.php /knowledgebase/ [R=301,L]
RewriteRule ^\/customer\/knowledgebase\.php$ /knowledgebase/ [R=301,L,QSA]
</IfModule>
重定向 URL 例如
https://www.example.com/customer/index.php?rp=/knowledgebase/5/DataNumen-Excel-Repair
到https://www.example.com/knowledgebase/
并重定向 URL 如
https://www.example.com/customer/knowledgebase.php
到https://www.example.com/knowledgebase/
但两者都不起作用。为什么?
更新
我尝试将 MrWhite 的代码从 /.htaccess 放到 /customer/.htaccess 并做了一些小的修改以适应这些变化,如下所示:
RewriteCond %{QUERY_STRING} rp=/knowledgebase/
RewriteRule ^index\.php$ https://www.example.com/knowledgebase/ [QSD,R=301,L,NC]
RewriteRule ^knowledgebase\.php$ https://www.example.com/knowledgebase/ [R=301,L,NC]
现在重定向可以正常工作了。但是,它只适用于以下情况:
https://www.example.com/customer/index.php?rp=/knowledgebase/9/DataNumen-PDF-Repair
但对于像
https://www.example.com/customer/index.php?a=b&c=d&rp=/knowledgebase/9/DataNumen-PDF-Repair
不管用。即使我在 RewriteCond 中将 ^rp= 改为 rp 也一样。
答案1
重写规则 ^/customer/index.php /knowledgebase/ [R=301,L]
在 中.htaccess
,匹配的 URL 路径RewriteRule
图案(即^\/customer\/index.php
)不以斜杠开头,因此永远不会匹配。匹配的 URL 路径相对于目录包含.htaccess
文件(减去斜杠前缀)。(不同于在服务器上下文,当匹配的 URL 路径是文档根目录相对 URL 路径时,以斜杠开头。)
您还需要QSD
第一条规则上的标志来丢弃原始请求中的查询字符串,否则将按原样传递。
小问题...在 Apache 正则表达式中,不需要对斜杠进行反斜杠转义,因为空格是参数分隔符,并且斜线在正则表达式中不具有任何特殊含义。
请尝试以下操作:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^rp=/knowledgebase/
RewriteRule ^customer/index\.php$ /knowledgebase/ [QSD,R=301,L]
RewriteRule ^customer/knowledgebase\.php$ /knowledgebase/ [R=301,L]
我将查询字符串锚定在状况因此它rp=...
与查询字符串的开头匹配,如您的示例所示。正则.*
表达式末尾的 不是必需的。
QSA
由于查询字符串默认通过,因此第二条规则不需要该标志。QSA
只有在需要时才需要该标志合并请求中的原始查询字符串与您在请求中附加的新查询字符串代换。
包装器<IfModule>
不是必需的,除非这些指令选修的并旨在用于 mod_rewrite 可能无法使用的多台服务器上。请参阅 Webmasters 堆栈上的这个问题:https://webmasters.stackexchange.com/questions/112600/is-checking-for-mod-write-really-necessary
您应该首先使用 302(临时)重定向进行测试,以避免潜在的缓存问题。
更新:为了简单起见,我将重写规则放在了
.htaccess
下的文件中/customer
,而不是/
。我已相应地更新了我的帖子。
在这种情况下,您需要删除customer/
每个RewriteRule
模式,正如您在更新后的问题中所做的那样。
如果rp
URL 参数旨在匹配查询字符串中的任何位置,那么您应该更改条件模式改为(^|&)rp=/knowledgebase/
,而不是简单地删除^
前缀。通过删除前缀,^
您可能会匹配太多内容,例如abcrp=/knowledgebase/...
也会匹配,尽管这在现实中可能是也可能不是问题。
否则,这些更新的指令看起来没问题,具体取决于可能与其他指令存在的任何其他冲突。缓存也可能是一个问题,特别是如果您使用 CDN。