使用 RewriteRule 时参数上不需要的反斜杠

Unwanted backslash on parameter while using RewriteRule

URL 示例:

1) mydomain.com/coding/mysql/
2) mydomain.com/coding/mysql/?contactId=333&UTM=aff
3) mydomain.com/coding/?contactId=333

这是我的 htaccess 文件

RewriteEngine On
RewriteRule ^(.+)/(.+)/?$ index.php?book=&chapter= [NC,L,QSA]
RewriteRule ^(.+)/?$ index.php?book= [NC,L,QSA]

所以我在 index.php 文件上 print_r($_REQUEST) 看看我得到了什么:

1) Array ( [book] => coding [chapter] => mysql/ )
2) Array ( [book] => coding [chapter] => mysql/ [contactId] => 333 [UTM] => aff )
3) Array ( [book] => coding/ [contactId] => 333 [UTM] => aff )

我的问题是我不想在最后一个可用参数中显示 / 如果我这样调用上面的示例,它不会添加 /:

1) mydomain.com/coding/mysql
2) mydomain.com/coding/mysql?contactId=333&UTM=aff
3) mydomain.com/coding?contactId=333

我需要更改什么规则才能使 mydomain.com/coding/mysql?contactId=333&UTM=aff 导致 Array ( [book] => coding [chapter] => mysql [contactId] => 333 [UTM] => aff )

谢谢!非常感激。我希望这是有道理的。

RewriteRule ^(.+)/(.+)/?$ index.php?book=&chapter= [NC,L,QSA]
RewriteRule ^(.+)/?$ index.php?book= [NC,L,QSA]

正则表达式默认是贪心的,所以在(.+)/?的情况下,捕获组会消耗后面的optional /

您可以像这样使量词非贪婪(即惰性):(.+?)/? 或匹配“除了斜线之外的任何东西”(即 [^/]+)而不是仅仅匹配“任何东西”(即 .+).

例如:

RewriteRule ^index\.php - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?book=&chapter= [L,QSA]
RewriteRule ^([^/]+)/?$ index.php?book= [L,QSA]

更新: 第一条规则只是为了防止重写循环,因为模式 ^([^/]+)/?$ 也会匹配 index.php(重写的 URL-路径).

此处不需要 NC 标志,因为您要同时匹配小写和大写 所有内容


但是,您应该与尾部斜线保持一致,包括尾部斜线或省略它 - 您不应该真的允许两者同时提供相同的内容。这可能是一个“重复内容”问题(两个 URL 服务相同的内容)。

如果您想同时允许两者,则 301 重定向 从一个到另一个。


更新:

yeah so I have a file locate at mydomain.com/library.php when I try to access it I get this instead of the actual file Array ( [book] => library.php )

(旁白: 如果您只是 matching/forcing 尾部斜杠 - 如评论中所述,那么这不一定是问题。)

这是因为上面的正则表达式相当通用。它匹配 /<any-path-segment>。如果您的 URLs(您想要重写)不包含点,那么您可以简单地在正则表达式中排除一个点,以避免匹配具有文件扩展名的“文件”(如 .php.js 等)。

例如,修改上面的正则表达式如下,排除点:

RewriteRule ^([^/.]+)/([^/.]+)/?$ index.php?book=&chapter= [L,QSA]
RewriteRule ^([^/.]+)/?$ index.php?book= [L,QSA]

这将匹配 foo,但不会匹配 foo.txt(因为它包含一个点)。

这也避免了需要第一个匹配 index.php 的规则,因为这自然会被更具体的正则表达式排除。

一般来说,您应该尽可能具体地使用正则表达式,只匹配需要的内容,以避免意外匹配太多。