Apache/2.4.54.
Estou tentando fazer com que URLs semelhantes (por exemplo, "/anystuff.htm") sejam redirecionados externamente para "/something", que internamente é "something.html". Mas as seguintes regras causam um loop em vez de parar, ou seja, "algo" é correspondido
RewriteEngine On
RewriteBase /
RewriteRule ^something$ something.html [L]
RewriteRule ^(some|thing|any|stuff).*/?$ /something [L, R=301,NC]
Mas parece que a diretiva "L" não tem efeito, porque o redirecionamento para "/alguma coisa" é correspondido novamente pela segunda regra, causando o loop.
Testando comhttps://htaccess.madewithlove.com/sugere que deve funcionar conforme o esperado. Acho que não consigo ativar o registro :-(
Responder1
O L
sinalizador apenas interrompe a passagem atual pelo mecanismo de reescrita, não paratodosem processamento. As diretivas a seguir não são processadas imediatamente, mas (em um contexto de diretório) o processo de reescrita é reiniciado... Durante a "segunda passagem", a primeira regra não corresponde mais (já que a entrada é now something.html
), mas a segunda regra sim, então aciona o redirecionamento.
(O mecanismo de reescrita efetivamente "faz um loop" até que a URL passe inalterada. As diretivas são mais fáceis de entender quando usadas em umservidorcontexto (não-diretório), onde o L
sinalizador efetivamente interrompe todo o processamento, uma vez que há apenas uma única passagem pelo mecanismo de reescrita.)
No entanto, no Apache 2.4 você pode usar o END
sinalizador para interromper todo o processamento pelo mecanismo de reescrita (em umdiretóriocontexto). Por exemplo:
RewriteEngine On
RewriteRule ^something$ something.html [END]
RewriteRule ^(some|thing|any|stuff) /something [R=301,NC,L]
(Observe que você teve um erroespaçono argumento flags na segunda regra. Isso teria resultado em um erro de análise, então presumo que foi um erro de digitação na sua pergunta?)
O regex final na segunda regra (ou seja, .*/?$
) é supérfluo.
Usar L
com um redirecionamento ( R
flag) é o mesmo que END
. Todo o processamento é interrompido.
A RewriteBase
diretiva é supérflua no seu exemplo.
NB: Você deve testar primeiro com um redirecionamento 302 (temporário) e só mudar para um 301 (permanente) quando tiver confirmado que funciona conforme o esperado. Os 301s são armazenados em cache persistentemente pelo navegador, o que pode tornar os testes problemáticos. Conseqüentemente, você precisará limpar os caches do navegador (e de qualquer intermediário) antes de testar.
Testar com
https://htaccess.madewithlove.com/
sugere que deve funcionar conforme o esperado.
Ao contrário de um servidor real, o testador MWL apenas (efetivamente) faz uma "passagem única" pelas regras, portanto não pode detectar loops de reescrita/redirecionamento.
Aparte:Normalmente, você deve organizar diretivas de redirecionamento externo antes de reescrever internamente. No entanto, a segunda regra em seuexemploredirecionaria /something
para si mesmo, portanto, suas duas diretivas dependem atualmente da ordem em que elas estão.