Eu converti algumas regras mod_rewrite para nginx e elas estavam funcionando bem quando eu testei localmente, mas por algum motivo elas não estão funcionando no meu site.
Alguém pode ajudar onde estou errando?
Regras do Apache:
<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>
Regras convertidas do 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;
}
O problema
Sua última regra de reescrita está fora de qualquer
location
bloco. Reconheço que não tenho certeza de como o nginx lida com os casos em que há uma regra de reescrita dentro e dentro de um bloco de localização correspondenteserver
(presumo que sempre usará o que está dentroserver
, pois é o que é avaliado primeiro). O que tenho certeza, porém, é que isso leva a resultados inesperados .A solução
Em primeiro lugar, se é mau . Não o use a menos que não haja absolutamente nenhuma outra maneira de obter o mesmo resultado (o que realmente só acontece em situações muito obscuras).
Uma alternativa melhor para verificar a existência de um arquivo é a diretiva try_files .
Suas regras de reescrita ficariam assim:
A última regra de reescrita, que provavelmente será a problemática, ficaria mais ou menos assim
try_files
dentro de seu próprio bloco de localização:O
~
modificador informa ao nginx que este local usa uma expressão regular. Ele corresponde a todos os URIs que terminam com.html
. Este bloco de localização tem preferência sobre os outros blocos de localização porque é mais específico (os blocos de localização de expressões regulares são examinados antes dos "normais"). Mais informações sobre a seleção de blocos de localização nginx .Notas e recursos adicionais
O
$
depois^/article.*
é redundante, pois você está combinando todos os caracteres atrás dele de qualquer maneira. Acrescentar?$args
ao URI datry_files
diretiva garante que todos osGET
parâmetros sejam passados para ele.