用于映射一个或两个参数的 Mod 重写规则



我有以下.htaccess:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f  
RewriteCond %{REQUEST_FILENAME} !-d  
RewriteRule ^/?([^/]+)/?$ /?page=$1 [L,QSA]  
RewriteRule ^/?([^/]+)/([^/]+)/?$ /?page=$1&id=$2 [L,QSA]  

此规则允许输入如下网址:

example.com/my-account-dashboard  
example.com/my-account-dashboard/1

哪些是漂亮的网址:

example.com?page=my-account-dashboard  
example.com?page=my-account-dashboard&id=1

到目前为止,这工作正常。但在内部,链接带有这些参数。如果可能的话,是否可以重定向(或其他东西(到漂亮的网址?对此的重写规则是什么?

首先,关于您当前包含一些错误的代码的一些评论。

1(RewriteCond仅适用于下一个RewriteRule。因此,您的第二个RewriteRule可以在没有该条件的情况下匹配(您可以尝试一下,您会看到(。您需要(再次(将该条件放在其他RewriteRule(或使用S跳过标志来模拟if/else条件,但它变得毫无意义(。

2(我很确定你不想像你那样使用QSA标记。通过使用它,您可以告诉mod_rewrite将任何查询字符串追加到重写中。示例:example.com/my-account-dashboard/?foo=bar将重写为/?page=my-account-dashboard&foo=bar。所以除非你真的想要它,否则你不需要它。很多人认为在重写中直接添加一些查询字符串时需要QSA,就像你一样。同样,这不是一个会使一切崩溃的错误,但它仍然不完全正确。

3(您的规则创建了对SEO(引用(不利的重复内容。例如,example.com/my-account-dashboardexample.com/my-account-dashboard/(注意尾部斜杠(都指向同一页面。但搜索引擎不会将它们视为相同。我邀请您在Google(或您喜欢的任何其他搜索引擎(上搜索"重复内容"并查看它。避免这种情况的一种简单方法是选择带或不带尾部斜杠。

现在基础已经明确,让我们回答你的问题。您不能简单地使用从旧网址到新网址的重定向R,因为最终会得到无限循环。这个问题有一些东西:THE_REQUEST.当mod_rewrite使用它时,它能够知道它来自直接客户端请求,而不是本身的重定向/重写。

多合一,以下是您的代码应该是什么样子:

RewriteEngine On
RewriteBase /
# Redirect old-url /?page=XXX to new-url equivalent /XXX
RewriteCond %{THE_REQUEST} s/?page=([^/&s]+)s [NC]
RewriteRule ^ /%1? [R=301,L]
# Redirect old-url /?page=XXX&id=YYY to new-url equivalent /XXX/YYY
RewriteCond %{THE_REQUEST} s/?page=([^/&s]+)&id=([0-9]+)s [NC]
RewriteRule ^ /%1/%2? [R=301,L]
# if /XXX is not a file/directory then rewrite to /?page=XXX
RewriteCond %{REQUEST_FILENAME} !-f  
RewriteCond %{REQUEST_FILENAME} !-d  
RewriteRule ^/?([^/]+)$ /?page=$1 [L]
# if /XXX/YYY is not a file/directory then rewrite to /?page=XXX&id=YYY
RewriteCond %{REQUEST_FILENAME} !-f  
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)/([0-9]+)$ /?page=$1&id=$2 [L]  

注意:我选择使用"无尾部斜杠"选项(例如example.com/my-account-dashboardexample.com/my-account-dashboard/1(。如果您愿意,请随时询问。

最新更新