Redirecionando URL não www para www usando .htaccess
-
09-06-2019 - |
Pergunta
estou a usar Reescrita ISAPI 3 da Helicon, que basicamente habilita .htaccess no IIS.Preciso redirecionar um URL não www para a versão www, ou seja,example.com deve redirecionar para www.example.com.Usei a seguinte regra dos exemplos, mas ela afeta subdomínios:
RewriteCond %{HTTPS} (on)?
RewriteCond %{HTTP:Host} ^(?!www\.)(.+)$ [NC]
RewriteCond %{REQUEST_URI} (.+)
RewriteRule .? http(?%1s)://www.%2%3 [R=301,L]
Isso funciona na maior parte, mas também redireciona sub.example.com para www.sub.example.com.Como posso reescrever a regra acima para que os subdomínios não sejam redirecionados?
Solução
Anexe o seguinte RewriteCond:
RewriteCond %{HTTP:Host} ^[^.]+\.[a-z]{2,5}$ [NC]
Dessa forma, a regra será aplicada apenas a nondottedsomething.uptofiveletters, como você pode ver, subdomain.domain.com não corresponderá à condição e, portanto, não será reescrito.
Você pode alterar [a-z]{2,5} para um regex de correspondência de tld mais estrito, bem como colocar todas as restrições para caracteres permitidos em nomes de domínio (já que [^.]+ é mais permissivo do que estritamente necessário).
Resumindo, acho que neste caso isso não seria necessário.
EDITAR:Sadie detectou uma falha no regex, mudou a primeira parte dele de [^.] para [^.]+
Outras dicas
Eu obtive mais controle usando urlrewriter.net, algo como:
<unless header="Host" match="^www\.">
<if url="^(https?://)[^/]*(.*)$">
<redirect to="$1www.domain.tld$2"/>
</if>
<redirect url="^(.*)$" to="http://www.domain.tld$1"/>
</unless>
Zigdon tem a ideia certa, exceto que seu regex não está certo.Usar
^example\.com$
em vez de sua sugestão de:
^example\.com(.*)
Caso contrário, você não corresponderá apenas a example.com, mas também a coisas como example.comcast.net, example.com.au, etc.
@Vinko
Para sua abordagem genérica, não sei por que você optou por limitar o comprimento do TLD em seu regex.Não é muito preparado para o futuro e não tenho certeza de quais benefícios ele oferece.Na verdade, nem é "à prova de agora" porque existe pelo menos um TLD de 6 caracteres (.museum) que não será correspondido.
Parece-me desnecessário fazer isso.Você não poderia simplesmente fazer ^[^.]+\.[^.]\+$
?(observação:o ponto de interrogação faz parte da frase, não da regex!)
Deixando tudo isso de lado, há um problema maior com essa abordagem que é:falhará em domínios que não estão diretamente abaixo do TLD.São domínios na Austrália, Reino Unido, Japão e muitos outros países, que possuem hierarquias:.co.jp, .co.uk, .com.au e assim por diante.
Se isso é ou não uma preocupação para o OP, não sei, mas é algo que você deve estar ciente se estiver procurando uma resposta "consertar tudo".
O OP ainda não deixou claro se deseja uma solução genérica ou uma solução para um único (ou pequeno grupo) de domínios conhecidos.Se for o último, veja minha outra observação sobre o uso da abordagem de Zigdon.Se for o primeiro, prossiga com a abordagem de Vinko levando em consideração as informações deste post.
Editar:Uma coisa que deixei de fora até agora, que pode ou não ser uma opção para você em termos de negócios, é seguir o outro caminho.Todos os nossos sites redirecionam http://www.domínio.com para http://domínio.com.O pessoal da http://no-www.org faça um bom argumento (IMHO) para que esta seja a maneira "certa" de fazer isso, mas certamente ainda é apenas uma questão de preferência.Uma coisa é certa: é muito mais fácil escrever uma regra genérica para esse tipo de redirecionamento do que esta.
@org 0100h Sim, há muitas variáveis deixadas de fora da descrição do problema, e todos os seus pontos são válidos e devem ser abordados no caso de uma implementação real.Existem prós e contras no seu regex proposto.Por um lado, é mais fácil e à prova de futuro; por outro, você realmente deseja corresponder example.foobar se enviado no cabeçalho Host?Pode haver alguns casos extremos em que você acabará redirecionando para o domínio errado.Uma terceira alternativa é modificar o regex para usar uma lista dos domínios reais, se houver mais de um, como
RewriteCond %{HTTP:Host} (example.com|example.net|example.org) [NC]
(Nota para Chris, aquele vai alterar% 1)
@chrisofspades Não foi feito para substituí-lo, sua condição número dois garante que não tenha www, enquanto a minha não.Não alterará os valores de %1, %2, %3 porque não armazena as correspondências (ai, não usa parênteses).
Você não pode ajustar o RewriteCond para operar apenas em example.com?
RewriteCond %{HTTP:Host} ^example\.com(.*) [NC]
Por que você não tem algo assim em seu arquivo vhost (de httpd)?
ServerName: www.example.com
ServerAlias: example.com
É claro que isso não redirecionará, isso continuará normalmente