
Estoy reescribiendo la configuración de Apache 2.4 que recibí del antiguo equipo de desarrollo.
Tengo ~200 líneas de configuración similar y no puedo entender según qué principio necesito cambiar este código para moverlo a .htaccess
virtualhost.
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^(.*)$ /$1/ [R,L,NC]
Cuando lo muevo al servidor virtual, mi sitio falla en lugares que no entiendo.
Respuesta1
Depende en qué parte del<VirtualHost>
contenedor coloque estas directivas.
Si estás usando un<Directory>
recipiente (es decir, undirectoriocontexto) ydeshabilitar .htaccess
anula por completo (¡de lo contrario .htaccess
anulará el <Directory>
contenedor!), entonces puede copiar las directivas tal como están (asumiendo que el <Directory>
contenedor hace referencia al mismo directorio que el .htaccess
archivo).
Sin embargo, si coloca estas directivas directamente dentro del <VirtualHost>
contenedor (fuera de un<Directory>
contenedor), es decir. en unanfitrión virtualcontexto, entonces necesitas hacer algunos cambios. Esto se debe a que las directivas se procesan antes, antes de que la solicitud se asigne al sistema de archivos.
En las directivas que ha publicado, solo se requerirían dos cambios:
en unanfitrión virtualcontexto, el
REQUEST_FILENAME
variable del servidor aún no se ha resuelto en unNombre del archivo. Es lo mismo queREQUEST_URI
(es decir, la URL que se solicita). Por lo tanto, la verificación de su sistema de archivos siempre fallará y la condición siempre será exitosa. O necesitas usar una anticipación. p.ej.%{LA-U:REQUEST_FILENAME}
, o construya usted mismo el nombre de archivo absoluto. p.ej.%{DOCUMENT_ROOT}%{REQUEST_URI}
. Por ejemplo:RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
en unanfitrión virtualcontexto, la ruta URL que coincide con el
RewriteRule
patrónes relativo a la raíz (comenzando con una barra). Mientras que en.htaccess
es relativo al directorio que contiene el.htaccess
archivo, menos el prefijo de barra diagonal. Por lo tanto, la regla tal como está escrita daría como resultado una doble barra al inicio de la ruta URL; en su lugar, debería reescribirse así:RewriteRule ^/(.*)$ /$1/ [R,L]
(La
NC
bandera no es necesaria aquí).O (preferiblemente) no use una referencia inversa aquí y use la variable del servidor en su lugar (que naturalmente también
REQUEST_URI
funcionaría )..htaccess
Por ejemplo:RewriteRule ^ %{REQUEST_URI}/ [R,L]
(Aparte:Probablemente esto también debería ser una redirección permanente 301 (es decir,
R=301
). Tal como está, esto será por defecto una redirección temporal 302. Pero solo cambie a un 301, si esa es la intención, una vez que haya confirmado que funciona según lo previsto).
Entonces, en resumen, esto quedaría:
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^/(.*)$ /$1/ [R,L]
Aparte:
Lo anterior se puede optimizar un poco inmediatamente moviendo la verificación del sistema de archivos (que es relativamentecaro) a la última condición y moviendo elcondiciónque comprueba que la solicitud no termina ya en una barra diagonal a la RewriteRule
directiva. Además, los subpatrones de expresiones regulares(.*)
en cada uno de loscondicionesno son necesarios. Entonces, lo anterior podría reescribirse de manera más eficiente:
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_URI} !^/application-module/
RewriteCond %{REQUEST_URI} !json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/ [NC]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule !/$ %{REQUEST_URI}/ [R,L]
La verificación del sistema de archivos quizás pueda eliminarse por completo si, en cambio, excluye las solicitudes que contienen (lo que parece) una extensión de archivo, pero esto puede depender de la estructura de su archivo.
Elcondiciónesa verificación !json$
parece que realmente debería verificar la .json
extensión del archivo, es decir.!\.json$
. (Esto se relaciona con mi comentario anterior sobre excluirtodosolicitudes que tienen una "extensión de archivo").
La primeracondicióneso verifica que la cadena de consulta esté vacía parece un poco extraño (ya que realmente no importa si hay una cadena de consulta o no cuando se agrega una barra a la ruta URL), pero supongo que esto debe ser un requisito específico.