Apache mod_rewrite
Lo que estás buscando es mod_rewrite ,
Descripción: proporciona un motor de reescritura basado en reglas para reescribir las URL solicitadas sobre la marcha.
En términos generales, mod_rewrite
funciona haciendo coincidir el documento solicitado con expresiones regulares especificadas, luego realiza reescrituras de URL internamente (dentro del proceso de Apache) o externamente (en el navegador del cliente). Estas reescrituras pueden ser tan simples como traducir internamente example.com/foo en una solicitud para example.com/foo/bar.
Los documentos de Apache incluyen una mod_rewrite
guía y creo que en ella se tratan algunas de las cosas que desea hacer. Guía detallada de mod_rewrite .
Forzar el www
subdominio
Me gustaría forzar "www" antes de cada URL, por lo que no es dominio.com sino www.dominio.com/página
La guía de reescritura incluye instrucciones para esto en el ejemplo de Canonical Hostname .
Eliminar barras inclinadas (parte 1)
Me gustaría eliminar todas las barras inclinadas de las páginas.
No estoy seguro de por qué querría hacer esto, ya que la guía de reescritura incluye un ejemplo para exactamente lo contrario , es decir, siempre incluye una barra al final. Los documentos sugieren que eliminar la barra inclinada tiene un gran potencial para causar problemas:
Problema de barra inclinada final
Descripción:
Cada webmaster puede cantar una canción sobre el problema de la barra al final de las URL que hacen referencia a directorios. Si faltan, el servidor arroja un error, porque si dices en /~quux/foo
lugar de, /~quux/foo/
entonces el servidor busca un archivo llamado foo. Y debido a que este archivo es un directorio, se queja. En realidad, intenta arreglarlo por sí mismo en la mayoría de los casos, pero a veces este mecanismo debe ser emulado por usted. Por ejemplo, después de haber realizado muchas reescrituras de URL complicadas en scripts CGI, etc.
¿Quizás podría explicar por qué desea eliminar la barra al final todo el tiempo?
Quitar .php
extensión
Lo necesito para eliminar el .php
Lo más parecido a hacer esto que se me ocurre es reescribir internamente cada documento de solicitud con una extensión .php, es decir, example.com/somepage se procesa en su lugar como una solicitud para example.com/somepage.php. Tenga en cuenta que proceder de esta manera requeriría que cada alguna página exista realmente como alguna página.php en el sistema de archivos.
Con la combinación correcta de expresiones regulares, esto debería ser posible hasta cierto punto. Sin embargo, puedo prever algunos posibles problemas con las páginas de índice que no se solicitan correctamente y que no coinciden con los directorios correctamente.
Por ejemplo, esto reescribirá correctamente example.com/test como una solicitud para example.com/test.php:
RewriteEngine on
RewriteRule ^(.*)$ $1.php
Pero hará que example.com no se cargue porque no hay example.com/.php
Supongo que si está eliminando todas las barras inclinadas, elegir una solicitud para un índice de directorio de una solicitud para un nombre de archivo en el directorio principal será casi imposible. ¿Cómo se determina una solicitud para el directorio 'foobar':
example.com/foobar
desde una solicitud de un archivo llamado foobar (que en realidad es foobar.php)
example.com/foobar
Podría ser posible si usó la RewriteBase
directiva. Pero si lo hace, este problema se complica mucho más, ya que necesitará RewriteCond
directivas para verificar el nivel del sistema de archivos si la solicitud se asigna a un directorio o archivo.
Dicho esto, si elimina el requisito de eliminar todas las barras diagonales finales y, en su lugar, fuerza la adición de barras diagonales finales, el problema de "sin extensión .php" se vuelve un poco más razonable.
# Turn on the rewrite engine
RewriteEngine on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
Esto todavía no es perfecto: cada solicitud de un archivo todavía tiene .php agregado a la solicitud internamente. Una solicitud de 'hi.txt' pondrá esto en sus registros de errores:
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
Pero hay otra opción, configure las directivas DefaultType
y DirectoryIndex
así:
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
Actualización 14-11-2013: se corrigió el fragmento anterior para incorporar la observación de nicorellius
Ahora las solicitudes de hi.txt (y cualquier otra cosa) tienen éxito, las solicitudes a example.com/test devolverán la versión procesada de test.php y los archivos index.php volverán a funcionar.
Debo dar crédito a quien se debe el crédito por esta solución, ya que la encontré en el blog de Michael J. Radwins buscando en Google php sin extensión apache .
Eliminar barras al final
Algunas búsquedas apache remove trailing slashes
me llevaron a algunas páginas de optimización de motores de búsqueda. Aparentemente, algunos sistemas de gestión de contenido (Drupal en este caso) harán que el contenido esté disponible con y sin una barra diagonal en las URL, lo que en el mundo del SEO hará que su sitio incurra en una penalización por contenido duplicado. Fuente
La solución parece bastante trivial, usando mod_rewrite
reescribimos con la condición de que el recurso solicitado termine en a /
y reescriba la URL enviando el 301 Permanent Redirect
encabezado HTTP.
Este es su ejemplo que asume que su dominio es blamcast.net y permite que la solicitud tenga el prefijo opcionalmente www.
.
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
Ahora estamos llegando a alguna parte. Pongamos todo junto y veamos cómo se ve.
Obligatorio www.
, no .php
y sin barras al final
Esto supone que el dominio es foobar.com y se ejecuta en el puerto estándar 80.
# Process all files as PHP by default
DefaultType application/x-httpd-php
# Fix sub-directory requests by allowing 'index' as a DirectoryIndex value
DirectoryIndex index index.html
# Force the domain to load with the www subdomain prefix
# If the request doesn't start with www...
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
# And the site name isn't empty
RewriteCond %{HTTP_HOST} !^$
# Finally rewrite the request: end of rules, don't escape the output, and force a 301 redirect
RewriteRule ^/?(.*) http://www.foobar.com/$1 [L,R,NE]
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
La bandera 'R' se describe en la RewriteRule
sección de la directiva. Retazo:
redirect|R [=code]
(forzar redirección) Sustitución de prefijo con
http://thishost[:thisport]/
(que convierte la nueva URL en un URI) para forzar una redirección externa. Si no se proporciona ningún código, se devolverá una respuesta HTTP de 302 ( MOVED TEMPORARILY ).
Nota final
No pude hacer que la eliminación de la barra oblicua funcionara correctamente. La redirección terminó dándome bucles de redirección infinitos. Después de leer la solución original más de cerca, tengo la impresión de que el ejemplo anterior les funciona debido a cómo está configurada su instalación de Drupal. Menciona específicamente:
En un sitio Drupal normal, con URL limpias habilitadas, estas dos direcciones son básicamente intercambiables
En referencia a las URL que terminan con y sin barra. Además,
Drupal usa un archivo llamado .htaccess
para decirle a su servidor web cómo manejar las URL. Este es el mismo archivo que habilita la magia de URL limpia de Drupal. Al agregar un comando de redireccionamiento simple al principio de su
.htaccess
archivo, puede forzar al servidor a eliminar automáticamente las barras al final.