Como o RewriteBase funciona no .htaccess

227

Eu já vi isso em alguns .htaccessexemplos

RewriteBase /

Parece ser um pouco semelhante em funcionalidade ao <base href="">HTML.

Eu acredito que ele pode acrescentar automaticamente seu valor ao início das RewriteRuledeclarações (possivelmente aquelas sem uma barra principal)?

Não consegui fazê-lo funcionar corretamente. Acho que seu uso pode ser muito útil para a portabilidade do site, pois geralmente tenho um servidor de desenvolvimento diferente de um servidor de produção. Meu método atual me permite excluir partes de minhas RewriteRuledeclarações.

Alguém pode me explicar brevemente como implementá-lo?

obrigado

alex
fonte
RewriteBase funciona apenas no diretório ou no contexto .htaccess ... consulte o contexto do link @SalmanPK fornecido.
Eddie B
1
Veja esta resposta para uma boa descrição. stackoverflow.com/a/2137593/292060
goodeye
1
Esta é uma resposta mais aprofundada: stackoverflow.com/a/21348047/632951
Pacerier
Esta é uma resposta de uma linha: stackoverflow.com/a/46541685/632951
Pacerier

Respostas:

102

Em minhas próprias palavras, depois de ler os documentos e experimentar:

Você pode usar RewriteBasepara fornecer uma base para suas reescritas. Considere isto

# invoke rewrite engine
    RewriteEngine On
    RewriteBase /~new/

# add trailing slash if missing
    rewriteRule ^(([a-z0-9\-]+/)*[a-z0-9\-]+)$ $1/ [NC,R=301,L]

Essa é uma regra real que usei para garantir que os URLs tenham uma barra final. Isso irá converter

http://www.example.com/~new/page

para

http://www.example.com/~new/page/

Ao ter RewriteBaselá, você faz o caminho relativo sair do RewriteBaseparâmetro.

alex
fonte
10
“Saia do parâmetro RewriteBase” - você quis dizer o parâmetro rewriteRule? :)
Kissaki 03/03
1
Quero esclarecer alguns detalhes sobre o htaccess. Um ReWriteBase o define para todas as regras no htaccess após a declaração? existe uma maneira de desmarcá-lo, ele pode ser redefinido?
21413 Damon
3
@Kissaki: Não, $1corresponde ao padrão RewriteRule entre parênteses, mas o caminho relativo para a substituição sai do parâmetro RewriteBase. Então, a substituição resultante é /~new/$1/.
precisa saber é o seguinte
3
@ Damon: Veja esta pergunta sobre várias RewriteBasediretivas. Em resumo, você não pode ter mais de um - acho que a última RewriteBase diretiva vence e afeta todo o arquivo .htaccess.
precisa saber é o seguinte
24
-1; esta resposta parece ter ajudado os outros, mas é totalmente opaca para mim. Eu poderia ter adivinhado que "você pode usar RewriteBasepara fornecer uma base para suas regravações" - que é praticamente apenas um rearranjo das palavras - mas não tenho idéia do que a "base" é , neste contexto, nem como o significado da o exemplo que você deu seria diferente se a RewriteBaselinha fosse removida. Off ao I go manual de ...
Mark Amery
89

RewriteBaseé aplicado apenas ao destino de uma regra de reescrita relativa .

  • Usando RewriteBase como este ...

    RewriteBase /folder/
    RewriteRule a\.html b.html
    
  • é essencialmente o mesmo que ...

    RewriteRule a\.html /folder/b.html
    
  • Mas quando o arquivo .htaccess está dentro /folder/, isso também aponta para o mesmo destino:

    RewriteRule a\.html b.html
    

Embora os documentos impliquem sempre o uso de a RewriteBase, o Apache geralmente o detecta corretamente para caminhos no DocumentRoot, a menos que:

  • Você está usando Aliasdiretivas

  • Você está usando regras de reescrita .htaccess para executar redirecionamentos HTTP (em vez de apenas reescrever silenciosamente) para URLs relativos

Nesses casos, você pode achar que precisa especificar o RewriteBase.

No entanto, como é uma diretiva confusa, geralmente é melhor especificar simplesmente URIs absolutos (também conhecidos como "root-root") em seus destinos de reescrita. Outros desenvolvedores que leem suas regras as entenderão mais facilmente.



Citando a excelente resposta detalhada de Jon Lin aqui :

Em um arquivo htaccess, mod_rewrite funciona de maneira semelhante a um <Directory>ou <Location>container. e o RewriteBaseé usado para fornecer uma base de caminho relativa.

Por exemplo, digamos que você tenha esta estrutura de pastas:

DocumentRoot
|-- subdir1
`-- subdir2
    `-- subsubdir

Então você pode acessar:

  • http://example.com/ (raiz)
  • http://example.com/subdir1 (subdir1)
  • http://example.com/subdir2 (subdir2)
  • http://example.com/subdir2/subsubdir (subsubdir)

O URI que é enviado por meio de RewriteRuleé relativo ao diretório que contém o arquivo htaccess. Então, se você tem:

RewriteRule ^(.*)$ - 
  • No htaccess raiz, e a solicitação é /a/b/c/d, então o URI ( $1) capturado é a/b/c/d.
  • Se a regra estiver dentro subdir2e a solicitação estiver /subdir2/e/f/g, o URI capturado estará e/f/g.
  • Se a regra estiver no subsubdire a solicitação estiver /subdir2/subsubdir/x/y/z, o URI capturado estará x/y/z.

O diretório em que a regra está possui essa parte removida do URI. A base de reescrita não afeta isso; é assim que funciona por diretório.

O que a base de reescrita faz é fornecer uma base de caminho de URL ( não uma base de caminho de arquivo) para quaisquer caminhos relativos no destino da regra . Então diga que você tem esta regra:

RewriteRule ^foo$ bar.php [L]

O bar.phpcaminho é relativo, em oposição a:

RewriteRule ^foo$ /bar.php [L]

onde o /bar.phpé um caminho absoluto. O caminho absoluto será sempre a "raiz" (na estrutura de diretórios acima). Isso significa que, independentemente de a regra estar na "raiz", "subdir1", "subsubdir" etc.), o /bar.phpcaminho sempre é mapeado para http://example.com/bar.php.

Mas a outra regra, com o caminho relativo, é baseada no diretório em que a regra está. Portanto, se

RewriteRule ^foo$ bar.php [L]

está na "raiz" e você acessa http://example.com/foo, é servido http://example.com/bar.php. Mas se essa regra estiver no diretório "subdir1" e você for http://example.com/subdir1/foo, será atendido http://example.com/subdir1/bar.php. etc. Isso às vezes funciona e às vezes não, como diz a documentação, é necessário para caminhos relativos, mas na maioria das vezes parece funcionar. Exceto quando você está redirecionando (usando a Rbandeira ou implicitamente porque você tem http://hostno destino da sua regra). Isso significa esta regra:

RewriteRule ^foo$ bar.php [L,R]

se é no diretório "subdir2", e você vai para http://example.com/subdir2/foo, mod_rewrite vai confundir o caminho relativo como um arquivo-caminho em vez de um URL-path e por causa da Rbandeira, você vai acabar sendo redirecionado para algo como: http://example.com/var/www/localhost/htdocs/subdir1. O que obviamente não é o que você deseja.

É aqui que RewriteBaseentra. A diretiva diz ao mod_rewrite o que acrescentar ao início de cada caminho relativo. Então, se eu tiver:

RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]

em "subsubdir", vou http://example.com/subdir2/subsubdir/foorealmente me servir http://example.com/blah/bar.php. O "bar.php" é adicionado ao final da base. Na prática, este exemplo geralmente não é o que você deseja, porque você não pode ter várias bases no mesmo contêiner de diretório ou arquivo htaccess.

Na maioria dos casos, é usado assim:

RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]

onde essas regras estariam no diretório "subdir1" e

RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]

estaria no diretório "subsubdir".

Em parte, isso permite que você torne suas regras portáteis, para que você possa descartá-las em qualquer diretório e precisar alterar apenas a base, em vez de várias regras. Por exemplo, se você tivesse:

RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...

tal que vai http://example.com/subdir1/fooservir http://example.com/subdir1/bar.phpetc. E diga que você decidiu mover todos esses arquivos e regras para o diretório "subsubdir". Em vez de alterar todas as instâncias de /subdir1/para /subdir2/subsubdir/, você poderia ter apenas uma base:

RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...

E então, quando você precisava mover esses arquivos e as regras para outro diretório, basta alterar a base:

RewriteBase /subdir2/subsubdir/

e é isso.

Simon East
fonte
Para mim, eu perdi RewriteEngine On. Não é necessário 1and1, por exemplo, mas é necessário no meu servidor dedicado.
Portekoi
41

AFAIK, RewriteBase é usado apenas para corrigir casos em que o mod_rewrite está sendo executado em um .htaccessarquivo que não está na raiz de um site e adivinha o caminho da Web errado (em oposição ao caminho do sistema de arquivos) para a pasta em que está sendo executado. RewriteRule em um .htaccess em uma pasta que mapeia para http://example.com/myfoldervocê pode usar:

RewriteBase myfolder

Se mod_rewrite não estiver funcionando corretamente.

Tentar usá-lo para obter algo incomum, em vez de corrigir esse problema, parece uma receita para ficar muito confuso.

rjmunro
fonte
2
Precisa terminar com uma barra final?
Pacerier 4/04
@self, No. Testado e
subexplicado
23

RewriteBase é útil apenas em situações em que você só pode colocar um .htaccess na raiz do seu site. Caso contrário, é melhor colocar os diferentes arquivos .htaccess em diretórios diferentes do site e omitir completamente a diretiva RewriteBase.

Ultimamente, para sites complexos, eu os expulso, porque torna a implantação de arquivos do teste em execução apenas mais uma etapa complicada.

Thomas Hunter II
fonte
22
Embora possa ser um bom conselho, essa não é uma resposta para a pergunta. Deveria, portanto, ter sido um comentário para a pergunta, não ter recebido (tantos) votos positivos e definitivamente não aceito como “resposta”.
Kissaki
3
"melhor colocar seus diferentes arquivos .htaccess em diretórios diferentes" - não tenho certeza se este é um bom conselho? A existência de arquivos .htaccess pontilhados em todo o site pode tornar a depuração / manutenção um pesadelo. Eu diria que é preferível ter um arquivo .htaccess na raiz do seu site.
precisa saber é o seguinte
1
@ w3d Há também uma questão de tempo: sempre que um subdiretório é acessado, vários arquivos .htaccess são analisados ​​(do raiz ao subdiretório atual). Ter um monte de arquivos pode diminuir a velocidade da resposta global ao pedido, em oposição a um único arquivo na raiz, mesmo se ele contém um monte de regras ..
Erenor Paz
19

Quando desenvolvo, ele está em um domínio diferente dentro de uma pasta. Quando coloco um site no ar, essa pasta não existe mais. O uso do RewriteBase permite que eu use o mesmo arquivo .htaccess nos dois ambientes.

Quando ao vivo:

RewriteBase /
# RewriteBase /dev_folder/

Ao desenvolver:

# RewriteBase /
RewriteBase /dev_folder/
user1669830
fonte
4
Tenho certeza que isso nem sempre funcionará. E se você usou %{REQUEST_URI}em uma RewriteConddiretiva, por exemplo?
precisa saber é o seguinte
1
@ user1669830, Se você tiver apenas uma reescrita, poderá adicionar a base à
reescrita
18

A explicação mais clara que encontrei não estava nos documentos atuais do apache 2.4, mas na versão 2.0 .

#  /abc/def/.htaccess -- per-dir config file for directory /abc/def
#  Remember: /abc/def is the physical path of /xyz, i.e., the server
#            has a 'Alias /xyz /abc/def' directive e.g.

RewriteEngine On

#  let the server know that we were reached via /xyz and not
#  via the physical path prefix /abc/def
RewriteBase   /xyz

Como funciona? Para você, hacker apache, este documento 2.0 fornece "informações detalhadas sobre as etapas de processamento interno".

Lição aprendida: Embora tenhamos que estar familiarizados com a "corrente", as gemas podem ser encontradas nos anais.

DWB
fonte
3

Este comando pode definir explicitamente o URL base para suas reescritas. Se você deseja iniciar na raiz do seu domínio, inclua a seguinte linha antes da RewriteRule:

RewriteBase /
Sandeep Goyal
fonte
2

Acredito que este trecho da documentação do Apache complementa bem as respostas anteriores:

Essa diretiva é necessária quando você usa um caminho relativo em uma substituição no contexto por diretório (htaccess), a menos que uma das seguintes condições seja verdadeira:

  • A solicitação original e a substituição estão embaixo do DocumentRoot (ao contrário de alcançáveis ​​por outros meios, como o Alias).

  • O caminho do sistema de arquivos para o diretório que contém o RewriteRule, com o sufixo da substituição relativa, também é válido como um caminho de URL no servidor (isso é raro).

Como mencionado anteriormente, em outros contextos, é útil apenas tornar sua regra mais curta. Além disso, também como mencionado anteriormente, você pode obter a mesma coisa colocando o arquivo htaccess no subdiretório.

alex
fonte