mod_rewrite, URLs limpas e diretórios de conteúdo da página

2

Estou usando o mod_rewrite em um arquivo .htaccess em nosso diretório da web raiz para que possamos usar URLs mais limpas para alguns casos específicos. Por exemplo, queremos traduzir:

http://example.com/Topic/ABCD/Type/Description

em

http://example.com/Topic.php?l=ABCD&e=Type&t=Description

Isso pareceu bastante fácil; o arquivo .htaccess consiste em:

RewriteEngine on
RewriteRule ^Topic/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /Topic.php?l=$1&e=$2&t=$3 [L]

No entanto, todo o conteúdo da página (arquivos .CSS, imagens, etc.) termina em 404'ing porque, em vez de, digamos, carregar "/Common.css" do diretório em relação à URL reescrita:

http://example.com/Common.css

ele é carregado a partir do diretório da URL não reescrita:

http://example.com/Topic/ABCD/Type/Description/Common.css

que obviamente não existe. No entanto, eu encontrei inúmeros tutoriais em toda a web que defendem alguma variante do que estou fazendo (um exemplo aqui ), mas não mencione esse problema que estou tendo, então estou pensando se há apenas alguma configuração que estou negligenciando. Eles não podem todos confiar em ter esses diretórios 'virtuais' existentes e conter o conteúdo da página. Eu também não quero fazer tudo em caminhos absolutos.

Eu tentei adicionar regras anteriores no arquivo .htaccess para tentar provocar um curto-circuito nas solicitações de conteúdo, como:

RewriteRule \.(css|jpe?g|gif|png)$ - [L]

mas parece não ter efeito. Independentemente disso, eu não teria pensado que tal conteúdo corresponderia à regra original, já que o regex dessa regra não permite nada seguindo a barra final (opcional).

Se eu alterar a regra de modo que seu sinalizador seja definido como redirecionado ([R, L] em vez de apenas [L]), tudo funcionará bem - exceto que agora o navegador exibe a string de parâmetro php reescrita, que é o que estávamos tentando evitar. No passado, acabamos de aceitar isso como uma solução, mas agora estou tentando entender por que ele está funcionando dessa maneira e o que posso fazer sobre isso.

Caso seja relevante, estou usando o CentOS 6.2 e o Apache / 2.2.15.

    
por Doug Kavendek 23.04.2012 / 23:47

3 respostas

2

O problema é mais provável que seu código gere páginas que incluam CSS da seguinte forma:

<link rel="stylesheet" type="text/css" href="Common.css" />

Como o navegador vê isso e vê o URL buscado como um subcaminho, ele faz uma solicitação para Common.css nesse subcaminho.

Você poderia (mas não deveria, por razões que explicarei daqui a pouco) fazer algumas regras de reescrita que reescrevem o Common.css etc para o único no nível superior, por exemplo:

RewriteEngine on
RewriteRule ^Topic/([^/.]+)/([^/.]+)/([^/.]+)/Common.css$ /Common.css [L]

No entanto, isso seria bobagem, já que todo o objetivo do CSS é permitir o armazenamento em cache, etc. Uma abordagem muito melhor é simplesmente adicionar um / na frente do Common.css em seu código, para que ele produza um CSS assim :

<link rel="stylesheet" type="text/css" href="/Common.css" />

Dessa forma, todas as páginas usam o mesmo arquivo Common.css, e o navegador não precisa buscar uma cópia do mesmo arquivo em vários locais lógicos em todas as páginas, e o que mais o navegador sabe para obtê-lo em o nível superior, não em uma subpágina.

PS Jakub: o regex para o RewriteRule já exclui qualquer coisa com um período, que já cobre o .css, .jpg, etc, então adicionar o RewriteCond adicional não ajudará.

    
por 24.04.2012 / 02:01
1

Você tem que usar o RewriteCond

RewriteEngine on
RewriteCond $1 !^(\.css|\.js|\.png|\.jpg)
RewriteRule ^Topic/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /Topic.php?l=$1&e=$2&t=$3 [L]
    
por 24.04.2012 / 01:33
1

A resposta é relativamente simples - você tem que usar base href em seu código html porque o processo de reescrever o URI redefine o URL base que causa os 404s que você está experimentando.

Há um bom artigo sobre isso no link

Cumprimentos Milhas

    
por 22.05.2012 / 12:29