我有以下.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-dashboard
和example.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-dashboard
和example.com/my-account-dashboard/1
(。如果您愿意,请随时询问。