.htaccess mod_rewrite muitos redirecionamentos

3

Apenas para esclarecer, NÃO se trata de uma pergunta duplicada como este como principal de questão é diferente. O que estou tentando fazer é redirecionar os usuários que tentam acessar um site usando um código de idioma (normalmente en ou cz ) para index.php com o conjunto de variáveis de idioma. O site em si pode reconhecer apenas as configurações de idiomas ingleses e tchecos, todos os outros são redirecionados com base na geolocalização do visitante (usando uma API JSON on-line externa). Mas o problema é que o navegador continua redirecionando e retorna um erro que muitos redirecionamentos ocorreram. O que há de errado? Tentei procurar um erro, mas não consegui ver nenhum.

Está completo o arquivo .htaccess :

Options -Indexes

RewriteEngine on
RewriteRule ^[a-z]{2,3}/$ /index.php?lang=$1
RewriteRule ^blog/?(.*)$ //blog.czghost.czlh/$1 [R=301]
RewriteRule ^ftp/?(.*)$ //ftp.czghost.czlh/$1 [R=301]

Além disso, se o usuário gravar em index.php?lang=$1 , eu preciso redirecioná-lo para a boa variante de URL. Eu procurei online, mas parece muito complicado para mim: (

Estou testando sites no meu servidor WAMP em minha máquina Windows, antes de estar pronto para implantar on-line.

    
por Polda18 01.04.2018 / 17:40

1 resposta

3

Você ainda não declarou a (s) URL (s) que está solicitando para acionar o loop de redirecionamento?

No entanto, nas diretivas que você postou, parece que qualquer solicitação do formulário /blog<anything> ou /ftp<anything> resultaria em um loop de redirecionamento.

RewriteRule ^blog/?(.*)$ //blog.czghost.czlh/$1 [R=301]
RewriteRule ^ftp/?(.*)$ //ftp.czghost.czlh/$1 [R=301]

O mod_rewrite do Apache não suporta URLs relativas a protocolos na RewriteRule substituição - elas são simplesmente vistas como relativas à raiz (ou seja, um caminho de URL relativo à raiz do documento). Você supostamente vê o resultado desse loop de redirecionamento na barra de endereços do seu navegador? Vai ser algo assim:

  • Solicitação inicial: http://example.com/blog/xyz
  • Redireciona para http://example.com//blog.czghost.czlh/xyz
  • Redireciona para http://example.com//blog.czghost.czlh/.czghost.czlh/xyz
  • Redireciona para http://example.com//blog.czghost.czlh/.czghost.czlh/.czghost.czlh/xyz
  • etc.

Você precisa incluir o protocolo. Por exemplo:

RewriteRule ^blog/?(.*)$ https://blog.czghost.czlh/$1 [R=301,L]

Eu também incluí o sinalizador L ( last ), pois você deseja que o redirecionamento seja acionado imediatamente, e não corre o risco de ser reescrito novamente. Isso deve vir antes da reescrita interna (que reescreve a index.php ).

Você precisará limpar o cache do navegador, pois o redirecionamento 301 ( permanente ) errôneo será armazenado em cache pelo navegador. Pode ser mais fácil testar com redirecionamentos 302 (temporários) por esse motivo.

Suas regras blog e ftp podem ser manipuladas por uma única diretiva, usando alternação . Por exemplo:

RewriteRule ^(blog|ftp)/?(.*)$ https://$1.czghost.czlh/$2 [R=301,L]
RewriteRule ^[a-z]{2,3}/$ /index.php?lang=$1

Você não tem um grupo de captura (ou seja, subpadrão entre parênteses) no padrão RewriteRule , portanto, a referência anterior $1 sempre estará vazia. Isso deve ser reescrito como:

RewriteRule ^([a-z]{2,3})/$ /index.php?lang=$1 [L]

Novamente, incluímos o L flag, para evitar mais reescritas. Observe que isso espera que haja um sufixo de barra no final do caminho da URL. Portanto, somente as URLs do formulário /blog/en/ (com um sufixo de barra) seriam reescritas com êxito (embora talvez isso não esteja relacionado).

Então, em resumo, isso deve ser reescrito como:

RewriteRule ^(blog|ftp)/?(.*)$ https://$1.czghost.czlh/$2 [R=301,L]
RewriteRule ^([a-z]{2,3})/$ /index.php?lang=$1 [L]

Also, if user writes in index.php?lang=$1, I need to redirect him to the nice URL variant instead.

Você pode fazer isso com um redirecionamento adicional antes das diretivas acima. Por exemplo:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^lang=([a-z]{2,3})$
RewriteRule ^(index\.php)?$ /%1/? [R=301,L]

Você precisa usar uma diretiva RewriteCond para verificar a string de consulta na variável QUERY_STRING server (isso não pode ser feito na diretiva RewriteRule ). A verificação anterior na variável de ambiente REDIRECT_STATUS é para garantir que processamos somente solicitações iniciais e não solicitações reescritas pela última diretiva que reconfigura a URL para /index.php?lang=xyz . O REDIRECT_STATUS env var está vazio na solicitação inicial, mas é definido como "200" (como em 200 OK - status HTTP) após a primeira reescrita bem-sucedida .

Isso corresponderá a index.php ou a um caminho de URL vazio (por exemplo, /?lang=xyz ). %1 é uma referência retroativa ao último CondPattern (em oposição a $N que é uma referência anterior ao padrão RewriteRule ). O ? no final da RewriteRule substituição é necessário para remover a string de consulta da URL redirecionada (alternativamente, você pode usar a flag QSD no Apache 2.4 +). / p>

Novamente, é melhor testar primeiro com um redirecionamento 302 (temporário) que não será armazenado em cache pelo navegador.

(From comments:) The only thing that works properly, is the /ftp/ redirect. /blog/ redirect stays with unchanged URL in a blank page

Você deve se certificar de que não exista nenhum diretório físico no sistema de arquivos com o mesmo nome, ex. %código%. E que esse subdiretório não tem um arquivo /blog adicional que pode estar substituindo isso. Além disso, certifique-se de que não exista um arquivo que compartilhe o mesmo nome de base .htaccess . por exemplo. blog ou blog.html etc. Se houver, você precisará garantir que o MultiViews (parte de mod_negotiation) não esteja ativado. ie. %código%. Se o MultiViews estiver ativado, o Apache fará uma subrequista interna para blog.php (por exemplo) antes que o mod_rewrite possa reescrever o URL.

Resumo

Options -Indexes -MultiViews

RewriteEngine on

# Redirect direct requests for "index.php?lang=xyz" to "/xyz/"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^lang=([a-z]{2,3})$
RewriteRule ^(index\.php)?$ /%1/? [R=301,L]

# Redirect "blog" or "ftp/<anything>" to subdomain
RewriteRule ^(blog|ftp)/?(.*)$ https://$1.czghost.czlh/$2 [R=301,L]

# Internally rewrite "/xyz/" to "/index.php?lang=xyz"
RewriteRule ^([a-z]{2,3})/$ /index.php?lang=$1 [L]
    
por 01.04.2018 / 19:17