Redirecionar, alterar URLs ou redirecionar HTTP para HTTPS no Apache - tudo o que você sempre quis saber sobre regras Mod_Rewrite, mas teve medo de perguntar


264

Esta é uma pergunta canônica sobre o mod_rewrite do Apache.

A alteração de um URL de solicitação ou o redirecionamento de usuários para um URL diferente daquele solicitado originalmente é feito com o mod_rewrite. Isso inclui coisas como:

  • Alterando HTTP para HTTPS (ou o contrário)
  • Alterando uma solicitação para uma página que não existe mais para uma nova substituição.
  • Modificando um formato de URL (como? Id = 3433 para / id / 3433)
  • Apresentar uma página diferente com base no navegador, com base no referenciador, com base em qualquer coisa possível sob a lua e o sol.
  • Tudo o que você quiser mexer com o URL

Tudo o que você sempre quis saber sobre as regras do Mod_Rewrite, mas teve medo de perguntar!

Como posso me tornar um especialista em escrever regras mod_rewrite?

  • Qual é o formato e a estrutura fundamentais das regras mod_rewrite?
  • De que forma / sabor das expressões regulares eu preciso ter uma sólida compreensão?
  • Quais são os erros / armadilhas mais comuns ao escrever regras de reescrita?
  • Qual é um bom método para testar e verificar regras mod_rewrite?
  • Existem implicações de SEO ou desempenho das regras mod_rewrite das quais devo estar ciente?
  • Existem situações comuns em que mod_rewrite pode parecer a ferramenta certa para o trabalho, mas não é?
  • Quais são alguns exemplos comuns?

Um lugar para testar suas regras

O site do testador de htaccess é um ótimo lugar para brincar com suas regras e testá-las. Ele até mostra a saída de depuração para que você possa ver o que correspondeu e o que não correspondeu.


9
A idéia por trás dessa pergunta é fornecer um caminho próximo para todas as infinitas perguntas sobre mod_rewrite que enlouquecem nossos usuários mais regulares. Isso é muito semelhante ao que foi feito com a sub-rede em serverfault.com/questions/49765/how-does-subnetting-work .
Kyle Brandt

1
Além disso, eu realmente não quero muitos votos positivos sobre essa questão , mas eles devem ir para a resposta. Não quero fazer isso por CW porque quero garantir que o pôster receba todo o crédito pelo que espero ser a resposta mod_rewrite para encerrar todas as perguntas do mod_rewrite .
Kyle Brandt

4
Desculpe, eu votei na pergunta. ;-) Eu realmente acho que ele precisa aparecer no (ou próximo) do topo das mod-rewritepesquisas / filtros de tags.
Steven segunda-feira

Someone Else (tm) deve lidar com os casos de uso comuns. Eu não os conheço o suficiente para fazer justiça.
sysadmin1138

Talvez essa pergunta deva ser vinculada ao wiki da tag mod-rewrite para tornar o caminho ainda mais curto.
beldaz

Respostas:


224

ordem de sintaxe mod_rewrite

mod_rewrite possui algumas regras de pedidos específicas que afetam o processamento. Antes que qualquer coisa seja feita, a RewriteEngine Ondiretiva precisa ser fornecida, pois isso ativa o processamento mod_rewrite. Isso deve ocorrer antes de qualquer outra diretiva de reescrita.

RewriteCondanterior RewriteRuletorna essa regra sujeita à condicional. Quaisquer RewriteRules a seguir serão processadas como se não estivessem sujeitas a condicionais.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html

Nesse caso simples, se o referenciador HTTP for de serverfault.com, redirecione as solicitações de blog para páginas especiais de falha do servidor (somos tão especiais assim). No entanto, se o bloco acima tiver uma linha RewriteRule extra:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg         $/blog/$1.sf.jpg

Todos os arquivos .jpg iriam para as páginas especiais de falha do servidor, não apenas aquelas com um referenciador indicando que ele veio daqui. Claramente, essa não é a intenção de como essas regras são escritas. Isso pode ser feito com várias regras RewriteCond:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

Mas provavelmente deve ser feito com alguma sintaxe de substituição mais complicada.

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

O RewriteRule mais complexo contém os condicionais para processamento. O último parênteses, (html|jpg)diz ao RewriteRule para corresponder a um htmlou jpg, e para representar a sequência correspondente como $ 2 na sequência reescrita. Isso é logicamente idêntico ao bloco anterior, com dois pares RewriteCond / RewriteRule, apenas o faz em duas linhas, em vez de quatro.

Várias linhas RewriteCond são implicitamente ANDed e podem ser explicitamente ORed. Para manipular referenciadores do ServerFault e do Superusuário (OR explícito):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)    [OR]
RewriteCond %{HTTP_REFERER}                ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Para veicular as páginas referidas ServerFault nos navegadores Chrome (AND implícito):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT}             ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

RewriteBasetambém é específico do pedido, pois especifica como as RewriteRulediretivas a seguir lidam com o processamento. É muito útil em arquivos .htaccess. Se usada, deve ser a primeira diretiva em "RewriteEngine on" em um arquivo .htaccess. Veja este exemplo:

RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Isso está dizendo ao mod_rewrite que esse URL específico que ele está manipulando chegou por meio de http://example.com/blog/ em vez do caminho do diretório físico (/ home / $ Username / public_html / blog) e para tratá-lo adequadamente. Por isso, RewriteRuleconsidera que o início da cadeia de caracteres está após o "/ blog" no URL. Aqui está a mesma coisa escrita de duas maneiras diferentes. Um com RewriteBase, o outro sem:

RewriteEngine On

##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER}                                   ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg)     $1.sf.$2

##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Como você pode ver, RewriteBasepermite reescrever regras para aproveitar o caminho do conteúdo do site em vez do servidor da web , o que pode torná-las mais inteligíveis para quem edita esses arquivos. Além disso, eles podem reduzir as diretrizes, o que tem um apelo estético.


Sintaxe de correspondência RewriteRule

O próprio RewriteRule possui uma sintaxe complexa para seqüências de caracteres correspondentes. Vou cobrir as bandeiras (coisas como [PT]) em outra seção. Como os administradores de sistemas aprendem pelo exemplo com mais frequência do que lendo uma página de manual, darei exemplos e explicarei o que eles fazem.

RewriteRule ^/blog/(.*)$    /newblog/$1

A .*construção corresponde a qualquer caractere único ( .) zero ou mais vezes ( *). Colocá-lo entre parênteses indica que você forneça a sequência que correspondeu à variável $ 1.

RewriteRule ^/blog/.*/(.*)$  /newblog/$1

Nesse caso, o primeiro. * NÃO foi colocado entre parênteses, portanto, não é fornecido para a sequência reescrita. Esta regra remove um nível de diretório no novo site do blog. (/blog/2009/sample.html se torna /newblog/sample.html).

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$2

Nesse caso, a primeira expressão entre parênteses configura um grupo correspondente. Isso se torna $ 1, o que não é necessário e, portanto, não é usado na string reescrita.

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$1/$2

Nesse caso, usamos $ 1 na string reescrita.

RewriteRule ^/blog/(20[0-9][0-9])/(.*)$   /newblog/$1/$2

Esta regra usa uma sintaxe de colchete especial que especifica um intervalo de caracteres . [0-9] corresponde aos números de 0 a 9. Esta regra específica tratará os anos de 2000 a 2099.

RewriteRule ^/blog/(20[0-9]{2})/(.*)$  /newblog/$1/$2

Isso faz o mesmo que a regra anterior, mas a parte {2} diz para ele corresponder ao caractere anterior (uma expressão de colchete nesse caso) duas vezes.

RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html   /newblog/$1/$2.shtml

Esse caso corresponderá a qualquer letra minúscula na segunda expressão correspondente e o fará com o máximo de caracteres possível. A \.construção diz para tratar o período como um período real, não como o caractere especial nos exemplos anteriores. Ele será interrompido se o nome do arquivo contiver traços.

RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html  /newblog/$1/$2.shtml

Isso intercepta nomes de arquivos com traços neles. No entanto, como -é um caractere especial nas expressões entre colchetes, ele deve ser o primeiro caractere na expressão.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Esta versão captura qualquer nome de arquivo com letras, números ou o -caractere no nome do arquivo. É assim que você especifica vários conjuntos de caracteres em uma expressão entre colchetes.


Sinalizadores RewriteRule

As bandeiras nas regras de reescrita têm vários significados e casos especiais .

RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html  /newblog/$1/$2.shtml  [L]

A bandeira está [L]no final da expressão acima. Vários sinalizadores podem ser usados, separados por vírgula. A documentação vinculada descreve cada uma, mas aqui estão elas de qualquer maneira:

L = Último. Pare de processar RewriteRules quando este corresponder. A ordem conta!
C = Cadeia. Continue processando a próxima RewriteRule. Se essa regra não corresponder, a próxima regra não será executada. Mais sobre isso mais tarde.
E = Definir variável ambiental. O Apache possui várias variáveis ​​ambientais que podem afetar o comportamento do servidor da web.
F = Proibido. Retorna um erro proibido 403 se esta regra corresponder.
G = Se foi. Retorna um erro 410-Gone se esta regra corresponder.
H = manipulador. Força a solicitação a ser tratada como se fosse o tipo MIME especificado.
N = Avançar. Força a regra a recomeçar e corresponder. SEJA CUIDADOSO! Loops podem resultar.
NC = Sem caso. Permitejpgpara corresponder a jpg e JPG.
NE = Sem escapatória. Impede a reescrita de caracteres especiais (.? # & Etc) em seus equivalentes de código hexadecimal.
NS = Nenhuma sub-solicitação. Se você estiver usando inclusões do lado do servidor, isso impedirá correspondências com os arquivos incluídos.
P = Proxy. Força a regra a ser manipulada por mod_proxy. Forneça de forma transparente o conteúdo de outros servidores, porque o seu servidor da Web o busca e serve novamente. Esta é uma bandeira perigosa, uma vez que uma mensagem mal escrita transformará seu servidor da Web em um proxy aberto e Isso é Ruim.
PT = Passagem Completa. Leve em conta as instruções de alias na correspondência RewriteRule.
QSA = QSAppend. Quando a string original contém uma consulta ( http://example.com/thing?asp=foo) anexa a string de consulta original à string reescrita. Normalmente seria descartado. Importante para conteúdo dinâmico.
R = Redirecionar. Forneça um redirecionamento HTTP para o URL especificado. Também pode fornecer código de redirecionamento exato [R = 303]. Muito parecido com o RedirectMatchque é mais rápido e deve ser usado quando possível.
S = Ignorar. Pule esta regra.
T = tipo. Especifique o tipo MIME do conteúdo retornado. Muito parecido com a AddTypediretiva.

Você sabe como eu disse que RewriteCondse aplica a uma e apenas uma regra? Bem, você pode contornar isso encadeando.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html     [C]
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

Como o primeiro RewriteRule possui o sinalizador Chain, a segunda regra de regravação será executada quando o primeiro, ou seja, quando a regra RewriteCond anterior for correspondida. Útil se as expressões regulares do Apache fizerem seu cérebro doer. No entanto, o método all-in-one-line que aponto na primeira seção é mais rápido do ponto de vista da otimização.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Isso pode ser simplificado através de sinalizadores:

RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html   /newblog/$1/$2.shtml   [NC]

Além disso, alguns sinalizadores também se aplicam ao RewriteCond. Notavelmente, NoCase.

RewriteCond %{HTTP_REFERER}        ^https?://serverfault\.com(/|$)     [NC]

Corresponderá a "ServerFault.com"


9
Bem feito. [filler]
EEAA

3
mod_rewritePrimer muito bom e regex. +1.
Steven segunda-feira

3
Às vezes, é útil saber que o RewriteCondprocesso é realmente processado após a RewriteRulecorrespondência. Você pode dizer "mais sobre isso mais tarde" na parte superior, onde diz "RewriteCond anterior à RewriteRule torna essa regra sujeita à condicional". Você pode mencionar que as expressões regulares são expressões regulares compatíveis com Perl. Além disso, você tem um apóstrofo estranho em "... o RewriteRule considera que é o início das cordas ..."
Dennis Williamson

2
RewriteRule ^/blog/.*/(.*)$ /newblog/$1não corresponde ao primeiro componente do diretório - por padrão, as regravações são gananciosas. /.*/(.*) corresponde a / 1 / (2) / e / 1/2/3/4/5 / (6) /, então você precisa de / [^ /] * / para corresponder apenas ao PRIMEIRO caminho componente.
adaptr

1
@ sysadmin1138, acho que essa resposta é boa, mas pode ser melhor se você elaborar mais sobre os sinalizadores E, N, NS, P, PT e S com exemplos, porque esses sinalizadores não são óbvios como eles funcionam etc.
Pacerier

39

Qual é o formato e a estrutura fundamentais das regras mod_rewrite?

Vou adiar a excelente resposta de sysadmin1138 sobre esses pontos.

De que forma / sabor das expressões regulares eu preciso ter uma sólida compreensão?

Além da ordem de sintaxe, da correspondência de sintaxe / expressões regulares e dos sinalizadores RewriteRule descritos por sysadmin1138, acredito que é importante mencionar que mod_rewrite expõe variáveis ​​de ambiente do Apache com base nos cabeçalhos de solicitação HTTP e na configuração do Apache.

Eu recomendaria o Tutorial de depuração do mod_rewrite do AskApache para uma lista abrangente de variáveis ​​que podem estar disponíveis para o mod_rewrite.

Quais são os erros / armadilhas mais comuns ao escrever regras de reescrita?

A maioria dos problemas com o RewriteRule resulta de um mal-entendido da sintaxe / falha do PCRE para escapar adequadamente de caracteres especiais ou da falta de percepção do conteúdo das variáveis ​​usadas para correspondência.

Problemas típicos e solução recomendada:

  • 500 - Erro interno do servidor - Remova os controles de carro do Windows no (s) arquivo (s) de configuração, se houver, verifique se mod_rewrite está ativado (encapsule diretivas IfModulecondicionais para evitar esse cenário), verifique a sintaxe da diretiva, comente as diretivas até que o problema seja identificado
  • Redirecionar loop - use RewriteLog e RewriteLogLevel, comente as diretivas até que o problema seja identificado

Qual é um bom método para testar e verificar regras mod_rewrite?

Primeiro, observe o conteúdo das variáveis ​​de ambiente com as quais você planeja comparar - se você possui o PHP instalado, é tão simples quanto adicionar o seguinte bloco ao seu aplicativo:

<?php
  var_dump($_SERVER);
?>

... escreva suas regras (de preferência para teste em um servidor de desenvolvimento) e observe qualquer correspondência ou atividade inconsistente no seu arquivo Apache ErrorLog .

Para regras mais complexas, use a RewriteLogdiretiva de mod_rewrite para registrar a atividade em um arquivo e definirRewriteLogLevel 3

Existem implicações de SEO ou desempenho das regras mod_rewrite das quais devo estar ciente?

AllowOverride allafeta o desempenho do servidor, pois o Apache deve procurar .htaccessarquivos e analisar diretivas a cada solicitação - se possível, mantenha todas as diretivas na configuração do VirtualHost para o seu site ou ative .htaccesssubstituições apenas para os diretórios que precisam delas.

As Diretrizes para webmasters do Google declaram explicitamente: "Não engane seus usuários nem apresente conteúdo diferente para os mecanismos de pesquisa que você exibe para os usuários, que geralmente é chamado de 'camuflagem'". - evite criar diretivas mod_rewrite que filtrem os robôs dos mecanismos de pesquisa.

Os robôs do mecanismo de pesquisa preferem um mapeamento de URI de conteúdo 1: 1 (esta é a base para classificar os links para o conteúdo) - se você estiver usando o mod_rewrite para criar redirecionamentos temporários ou se estiver exibindo o mesmo conteúdo em vários URIs, considere especificar um URI canônico dentro seus documentos HTML.

Existem situações comuns em que mod_rewrite pode parecer a ferramenta certa para o trabalho, mas não é?

Este é um tópico enorme (e potencialmente controverso) por si só - melhor (IMHO) para abordar os usos caso a caso e permitir que os solicitantes determinem se as resoluções sugeridas são adequadas às suas necessidades.

Quais são alguns exemplos comuns?

Os truques e dicas do mod_rewrite do AskApache cobrem quase todos os casos de uso comuns que aparecem regularmente; no entanto, a solução "correta" para um determinado usuário pode depender da sofisticação da configuração do usuário e das diretivas existentes (é por isso que geralmente é um É uma boa idéia ver quais outras diretivas um usuário possui sempre que uma pergunta mod_rewrite surgir).


Obrigado pelo link AskApache. É o que eu estava procurando!
sica07

O palhaço AskApache não é oficialmente suportado pelo ASF. Muito do que ele diz é discutível ou claramente errado.
adaptr

@adaptr Compartilhe os recursos superiores dos quais você aparentemente conhece.
Danlefree 13/04/12

"situações comuns em que mod_rewrite pode parecer a ferramenta certa para o trabalho, mas não é?" - redirecionamentos simples , onde mod_rewrite ainda não está sendo usado. Use mod_alias Redirectou, em RedirectMatchvez disso. Veja também os documentos do Apache: Quando não usar mod_rewrite
MrWhite 8/16/16

21

Como muitos administradores / desenvolvedores, venho lutando contra os meandros da reescrita de regras há anos e estou insatisfeito com a documentação existente do Apache, então decidi como um projeto pessoal descobrir como mod_rewriterealmente funciona e interage com o restante do Apache. nos últimos meses, tenho instrumentado casos de teste com strace+ drill no código-fonte para entender tudo isso.

Aqui estão alguns comentários importantes que reescrevem os desenvolvedores de regras que devem ser considerados:

  • Alguns aspectos da reescrita são comuns à configuração do servidor, host virtual, diretório, processamento de .htaccess .
  • Algum processamento é muito diferente para a configuração raiz (configuração do servidor, host virtual e diretório), em oposição ao .htaccessprocessamento PerDir ( ).
  • Pior ainda, porque o processamento do PerDir pode quase indiscriminadamente acionar o ciclo INTERNAL REDIRECT, os elementos de configuração raiz precisam ser escritos, cientes de que esse processamento do PerDir pode acionar isso.

Eu diria que, por causa disso, você quase precisa dividir as comunidades de usuários reescritos em duas categorias e tratá-las como completamente separadas:

  • Aqueles com acesso root à configuração do Apache . Normalmente, eles são admin / developer com um servidor / VM dedicado a aplicativos, e a mensagem aqui é bastante simples: evite usar .htaccessarquivos, se possível; faça tudo na sua configuração de servidor ou vhost. A depuração é bastante fácil, pois o desenvolvedor pode definir a depuração e ter acesso aos arquivos rewrite.log.

  • Usuários de um serviço hospedado compartilhado (SHS) .

    • Esses usuários precisam usar o .htaccessprocessamento / Perdir, pois não há alternativa disponível.
    • Pior, o nível de habilidade desses usuários (na medida em que usa a lógica ladder do mod_rewrite orientada por regexp) geralmente é significativamente menor do que os administradores experientes.
    • O Apache e os provedores de hospedagem não oferecem suporte a depuração / diagnóstico. As únicas informações de diagnóstico são um redirecionamento bem-sucedido, um redirecionamento para o URI errado. ou um código de status 404/500. Isso os deixa confusos e desamparados.
    • O Apache é extremamente fraco, explicando como a reescrita funciona para este caso de uso. Por exemplo, ele não fornece uma explicação clara de qual .htaccessarquivo PerDir está selecionado e por quê. Ele não explica os meandros do ciclismo PerDir e como evitar isso.

Existe possivelmente uma terceira comunidade: a administração e a equipe de suporte dos provedores de SHS que terminam com o pé nos dois campos e sofrem as consequências do exposto acima.

Escrevi algumas postagens no blog no estilo de artigo (por exemplo, mais sobre o uso de regras de reescrita em arquivos .htaccess ), que abordam muitos pontos detalhados que não repetirei aqui para manter esta postagem curta. Eu tenho meu próprio serviço compartilhado, além de apoiar alguns projetos dedicados e VM FLOSS. Comecei usando uma VM LAMP padrão como veículo de teste para minha conta SHS, mas no final achei melhor fazer uma VM espelhada adequada (descrita aqui ).

No entanto, em termos de como a comunidade de administradores deve dar suporte .htaccessaos usuários, sinto que precisamos desenvolver e oferecer:

  • Uma descrição coerente de como o sistema de reescrita realmente funciona no processamento do PerDir
  • Um conjunto de diretrizes / práticas recomendadas sobre como escrever .htaccessregras de reescrita
  • Um analisador de script de reescrita simples baseado na Web, semelhante aos analisadores de html W3C, mas pelo qual os usuários podem inserir URIs de teste ou vetores de teste dos mesmos e obter um log imediato do fluxo lógico de reescrita /
  • Dicas sobre como obter diagnósticos embutidos de suas regras (por exemplo,

    • Use a [E=VAR:EXPR]exploração do fato que EXPRexpandirá as referências anteriores ($ N ou% N) para torná-las disponíveis como diagnóstico para o script de destino.
    • Se você ordenar topicamente suas regras de reescrita usando os sinalizadores [OR], [C], [SKIP] e [L] para que todo o esquema de reescrita funcione sem a necessidade de explorar o redirecionamento interno, você poderá adicionar o seguinte como regra 1 para evitar todos os problemas de loop:

      RewriteCond %{ENV:REDIRECT_STATUS} !=""
      RewriteRule .  -  [L]
      

Isso está bem documentado. Por que você diz que a documentação não explica isso?
adaptr

2
Tudo que você precisa fazer é se inscrever nos .htaccesstópicos e você verá. A maioria dos iniciantes fica irremediavelmente confusa - a maioria deles tem sua primeira experiência com um serviço LAMP e mod_rewrite em um serviço compartilhado e, portanto, não tem acesso root às configurações do sistema / vhost e precisa usar o processamento por diretório através de .htaccessarquivos. Existem diferenças importantes que o iniciante precisa "sangrar". Eu me consideraria um usuário avançado e ainda estou descobrindo sutilezas. Como já disse, tive que usar a varredura de strace e de código-fonte para resolver alguns aspectos. Não deve ser necessário. :-(
TerryE

Eu concordo totalmente. "Precisamos dividir as comunidades de usuários reescritos em duas categorias e tratá-las como completamente separadas". Alguns usuários estão usando hospedagem compartilhada e precisam confiar .htaccess, o que é terrivelmente frágil, complicado e confuso, mesmo para especialistas. Eu ainda estou tendo problemas.
19717 Ryan

15

Usando reescrever mapa

Há muitas coisas que você pode fazer com reescrever mapas. Os Rewritemaps são declarados usando a diretiva Rewritemap e podem ser usados ​​nas avaliações RewritCond e nas Subscrições RewriteRule.

A sintaxe geral do RewriteMap é:

RewriteMap MapName MapType:MapSource

Por exemplo:

RewriteMap examplemap txt:/path/to/file/map.txt

Você pode usar o nome do mapa para construções como esta:

${examplemap:key}

O mapa contém pares de chave / valor. Se a chave for encontrada, o valor será substituído. Mapas simples são apenas arquivos de texto sem formatação, mas você pode usar mapas de hash e até consultas SQL. Mais detalhes estão nos documentos:

http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap

Cordas sem escape.

Existem quatro mapas internos que você pode usar para fazer algumas manipulações. Especialmente seqüências de caracteres sem escape podem ser úteis.

Por exemplo: eu quero testar a string "café" na string de consulta. No entanto, o navegador escapará disso antes de enviá-lo para o meu servidor, portanto, eu preciso descobrir qual é a versão com escape de URL para cada string que eu desejo corresponder, ou posso simplesmente desescapá-la ...

RewriteMap unescape int:unescape

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   café
RewriteRule ^/find/$         /find/1234? [L,R]

Observe como eu uso um RewriteCond para capturar apenas o argumento do parâmetro de cadeia de consulta e, em seguida, use o mapa no segundo rewriteCond para removê-lo. Isso então é comparado. Observe também como eu preciso% 2 como chave no mapa de reescrita, pois% 1 conterá "location" ou "place". Quando você usa parênteses para agrupar padrões, eles também serão capturados, se você planeja usar o resultado da captura ou não ...


A última frase não é bem verdadeira. O mod_rewritemecanismo regexp suporta grupos não capturadores como (?:location|place)e isso terá apenas uma captura no exemplo.
TerryE

12

Quais são os erros / armadilhas mais comuns ao escrever regras de reescrita?

Uma armadilha muito fácil é quando você reescreve URLs que alteram o caminho aparente, por exemplo, de /base/1234/index.htmlpara /base/script.php?id=1234. Quaisquer imagens ou CSS com caminhos relativos ao local do script não serão encontrados pelo cliente. Várias opções para resolver isso podem ser encontradas neste FAQ .


1
Obrigado pelo link. Particularmente ao trabalhar com outros membros da equipe que não estão familiarizados com a reescrita, acho que a adição de uma <base>tag é mais fácil de seguir e ainda permite caminhos relativos.
kontur
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.