我为 nginx 转换了一些 mod_rewrite 规则,当我在本地测试时它们工作正常,但由于某种原因它们在我的网站上不起作用。
任何人都可以帮助我出错的地方吗?
阿帕奇规则:
<filesMatch "\.(htm|html|css|js|php)$">
AddDefaultCharset UTF-8
DefaultLanguage en-US
</filesMatch>
<IfModule mod_rewrite.c>
ErrorDocument 404 /404.php
RewriteEngine On
RewriteRule ^article.*$ / [R=301,L]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*\.* /loadpage.php [QSA,L]
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*\.html /courses/index.php [L]
</IfModule>
Nginx 转换规则:
charset utf-8;
error_page 404 /404.php;
location /article {
rewrite ^/article.*$ / redirect;
}
location / {
if (!-e $request_filename){
rewrite ^/.*\.* /loadpage.php break;
}
}
if (!-e $request_filename){
rewrite ^/.*\.html /courses/index.php break;
}
问题
您的最后一个重写规则在任何
location
块之外。诚然,我不确定 nginx 如何处理匹配位置块内和内部都存在重写规则的情况server
(我假设它将始终使用内部的规则server
,因为这是首先评估的)。然而,我可以肯定的是,这会导致意想不到的结果。解决方案
首先,如果是邪恶的。不要使用它,除非绝对没有其他方法可以达到相同的结果(这实际上只发生在非常模糊的情况下)。
检查文件是否存在的更好替代方法是try_files指令。
您的重写规则将如下所示:
try_files
最后一个重写规则,可能是有问题的规则,在其自己的位置块内看起来像这样:修饰符告诉 nginx这个
~
位置使用正则表达式。它匹配所有以 . 结尾的 URI.html
。此位置块优先于其他位置块,因为它更具体(在“正常”位置块之前检查正则表达式位置块)。有关 nginx 位置块选择的更多信息。附加说明和资源
$
after是多余的^/article.*
,因为无论如何你都要匹配它后面的所有字符。附加?$args
到try_files
指令的 URI 可确保所有GET
参数都传递给它。