我有以下.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
到目前为止,此工作正常。但内部链接是这些参数。如果可能的话,是否可以将重定向(或其他内容)重定向到漂亮的URL? 有哪些重写规则?
答案 0 :(得分:1)
首先,关于当前代码包含一些错误的一些评论。
1)RewriteCond
仅适用于下一个RewriteRule
。所以你的第二个RewriteRule
可以在没有这个条件的情况下匹配(你可以尝试一下,你会看到)。你需要将那个条件(再次)放到另一个RewriteRule
(或者使用S
skip标志来模拟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(或您喜欢的任何其他搜索引擎)上查看它。避免这种情况的一种简单方法是使用或不使用尾部斜杠。
现在基础已经清楚了,让我们回答你的问题。您不能简单地使用从old-url到new-url的重定向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
)。随意询问您是否愿意。