Saltar al contenido

Configuración de .htaccess adecuada para Next.js SSG

Hola, hallamos la solución a tu búsqueda, deslízate y la verás un poco más abajo.

Solución:

Si lo solicita /article y /article existe como un directorio físico, entonces el mod_dir de Apache, agregará (por defecto) la barra al final para “arreglar” la URL. Esto se logra con un redireccionamiento permanente 301, por lo que el navegador lo almacenará en caché.

Aunque tener un directorio físico con el mismo nombre de base que un archivo y usar URL sin extensión crea una ambigüedad. p.ej. Es /article se supone que debe acceder al directorio /article/ o el archivo /article.html. No parece que desee permitir el acceso directo a los directorios de todos modos, por lo que parecería resolver esa ambigüedad.

Para evitar que Apache mod_dir agregue la barra al final a los directorios, debemos deshabilitar la DirectorySlash. Por ejemplo:

DirectorySlash Off

Pero como se mencionó, si ha visitado previamente /article luego la redirección a /article/ habrá sido almacenado en caché por el navegador, por lo que deberá borrar el caché del navegador antes de que esto sea efectivo.

Dado que está eliminando la extensión del archivo, también debe asegurarse de que MultiViews esté deshabilitado; de lo contrario, mod_negotiation emitirá una solicitud secundaria interna para el archivo subyacente y, potencialmente, entrará en conflicto con mod_rewrite. MultiViews está deshabilitado de forma predeterminada, aunque algunos hosts compartidos lo habilitan por alguna razón. Por la salida que está obteniendo, no parece que MultiViews esté habilitado, pero es mejor estar seguro …

# Ensure that MutliViews is disabled
Options -MultiViews

Sin embargo, si necesita poder acceder al directorio en sí, deberá agregar manualmente la barra al final con una reescritura interna. Aunque esto no parece ser un requisito aquí. Sin embargo, debe asegurarse de que las listas de directorios estén deshabilitadas:

# Disable directory listings
Options -Indexes

Intentar acceder a cualquier directorio (que en última instancia no se asigna a un archivo, ver más abajo) y no contiene un DirectoryIndex El documento devolverá una respuesta 403 Forbidden, en lugar de una lista de directorio.

Tenga en cuenta que la única diferencia que podría ocurrir entre seguir un enlace a domain/article, actualizando la página y escribiendo manualmente domain/article es almacenamiento en caché … ya sea por el navegador o cualquier caché de proxy intermediario. (¡¿A menos que tenga JavaScript que intercepte el evento de clic en el ancla ?!)

Aún necesita reescribir las solicitudes de /foo para /foo.html O /foo para /foo/index.html (ver más abajo), dependiendo de cómo haya configurado su sitio. Aunque sería preferible que elijas uno u otro, en lugar de ambos (como parece que podría ser el caso).

RewriteCond %REQUEST_FILENAME !-d
RewriteCond %REQUEST_FILENAME.html -f
RewriteRule ^(.*)$ $1.html

No está claro cómo esto aparentemente “funciona” para usted actualmente, a menos que vea una respuesta en caché. Cuando lo solicitas /article, la primera condición falla porque existe como un directorio físico y la regla no se procesa. Incluso con MultiViews habilitado, mod_dir tendrá prioridad y agregará la barra al final.

La segunda condición que comprueba la existencia de la .html archivo no necesariamente está comprobando el mismo archivo en el que se está reescribiendo. p.ej. Si lo solicita /foo/bar, dónde /foo.html existe, pero no hay un directorio físico /foo entonces el RewriteCond la directiva verifica la existencia de /foo.html – que tiene éxito, pero la solicitud se reescribe internamente a /foo/bar.html (del capturado RewriteRulepatrón): esto da como resultado un bucle de reescritura interno y una respuesta de error 500 que se devuelve al cliente. Vea mi respuesta a la siguiente pregunta de ServerFault que explica con más detalle lo que realmente está sucediendo aquí.

También podemos realizar una optimización adicional si asumimos que cualquier URL que contenga lo que parece una extensión de archivo (por ejemplo, su static recursos .css, .js y archivos de imagen) deben ignorarse, de lo contrario, estamos realizando verificaciones del sistema de archivos en cada solicitud, lo cual es relativamente costoso.

Entonces, para mapear (reescribir internamente) solicitudes del formulario /article para /article.html y /article/somearticle para /article/somearticle.html necesitaría modificar la regla anterior para leer algo como:

# Rewrite /foo to /foo.html if it exists
RewriteCond %DOCUMENT_ROOT%REQUEST_URI.html -f
RewriteRule !.w2,4$ %REQUEST_URI.html [L]

No es necesario que la barra invertida escape de un punto literal en el RewriteCondTestString – el punto no tiene ningún significado especial aquí; no es una expresión regular.

Luego, para manejar solicitudes del formulario /foo que debería mapear a /foo/index.html puedes hacer algo como lo siguiente:

# Rewrite /foo to /foo/index.html if it exists
RewriteCond %DOCUMENT_ROOT%REQUEST_URI/index.html -f
RewriteRule !.w2,4$ %REQUEST_URI/index.html [L]

Normalmente, permitiría que mod_dir sirva el DirectoryIndex (p.ej. index.html), pero habiendo omitido la barra al final del directorio, esto puede ser problemático.

Resumen

Reuniendo los puntos anteriores, tenemos:

# Disable directory indexes and MultiViews
Options -Indexes -MultiViews

# Prevent mod_dir appending a slash to directory requests
DirectorySlash Off

# Rewrite /foo to /foo.html if it exists
RewriteCond %DOCUMENT_ROOT%REQUEST_URI.html -f
RewriteRule !.w2,4$ %REQUEST_URI.html [L]

# Otherwise, rewrite /foo to /foo/index.html if it exists
RewriteCond %DOCUMENT_ROOT%REQUEST_URI/index.html -f
RewriteRule !.w2,4$ %REQUEST_URI/index.html [L]

Esto podría optimizarse aún más, dependiendo de la estructura de su sitio y si está agregando más directivas al .htaccess expediente. Por ejemplo:

  1. puede verificar las extensiones de archivo en la URL solicitada en la parte superior del archivo para evitar cualquier procesamiento posterior. los RewriteRule La expresión regular en cada regla subsiguiente podría entonces “simplificarse”.
  2. Las solicitudes que incluyen una barra inclinada final se pueden bloquear o redirigir (para eliminar la barra inclinada final).
  3. Si la solicitud es para un .html luego redirigir a la URL sin extensión. Esto se vuelve un poco más complicado si se trata de ambos /foo.html y /foo/index.html. Pero esto solo es realmente necesario si cambiando una estructura de URL existente.

Por ejemplo, implementar # 1 y # 2 anteriores, permitiría que las directivas se escribieran así:

# Disable directory indexes and MultiViews
Options -Indexes -MultiViews

# Prevent mod_dir appending a slash to directory requests
DirectorySlash Off

# Prevent any further processing if the URL already ends with a file extension
RewriteRule .w2.4$ - [L]

# Redirect any requests to remove a trailing slash
RewriteRule (.*)/$ /$1 [R=301,L]

# Rewrite /foo to /foo.html if it exists
RewriteCond %DOCUMENT_ROOT/$1.html -f
RewriteRule (.*) $1.html [L]

# Otherwise, rewrite /foo to /foo/index.html if it exists
RewriteCond %DOCUMENT_ROOT/$1/index.html -f
RewriteRule (.*) $1/index.html [L]

Pruebe siempre con una redirección 302 (temporal) antes de cambiar a una redirección 301 (permanente) para evitar problemas de almacenamiento en caché.

Al final de todo puedes encontrar las notas de otros usuarios, tú asimismo tienes la libertad de dejar el tuyo si te gusta.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *