Htaccess: agregar / eliminar barra al final de la URL


81

Mi sitio web ejecuta un script llamado -> Script de fondo de pantalla de WSS

Mi problema -> He intentado forzar la eliminación o agregar una barra al final de mi URL para evitar el contenido duplicado y también para limpiar mis URL.

He probado todo tipo de cosas y he probado todo lo que podía pensar y muchas cosas de las redes, ¡pero todavía no tuve tanta suerte! Puede que sea una solución rápida, pero lo he mirado tanto que probablemente estoy ciego ante algo totalmente obvio.

Así que les presento todo mi .htaccesscódigo:

DirectoryIndex index.php

RewriteEngine on
RewriteRule ^download/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) image.php?id=$1&width=$2&height=$3&cropratio=$4&download=1 [L]
RewriteRule ^file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) image.php?id=$1&width=$2&height=$3&cropratio=$4 [L]
RewriteRule ^preview/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) wallpaper_preview.php?id=$1&width=$2&height=$3&name=$4 [L]
RewriteRule ^thumbnail/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/]+) image.php?wallpaper_id=$1&width=$2&height=$3&cropratio=$4&align=$5&valign=$6&file=$7 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/p([0-9]+) index.php?task=category&id=$1&name=$2&page=$3 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/([0-9a-zA-Z?-]+)/p([0-9]+) index.php?task=category&id=$1&name=$2&sortby=$3&page=$4 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/([0-9a-zA-Z?-]+)-([0-9]+) index.php?task=category&id=$1&sortby=$3&page=$4 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+) index.php?task=category&id=$1&name=$2 [L]
RewriteRule ^tag/([^/\.]+)/([0-9a-zA-Z?-]+)/([0-9]+) index.php?task=tag&t=$1&sortby=$2&page=$3 [L]
RewriteRule ^tag/([^/\.]+) index.php?task=tag&t=$1 [L]
RewriteRule ^profile/([0-9]+)?/([^/\.]+) index.php?task=profile&id=$1&name=$2 [L]
RewriteRule ^profile/comments/([0-9]+)?/([^/\.]+) index.php?task=users_comments&id=$1&name=$2 [L]
RewriteRule ^page/([0-9]+) index.php?task=view_page&id=$1 [L]  
RewriteRule ^register index.php?task=register [L] 
RewriteRule ^lost-password index.php?task=lost_pass [L] 
RewriteRule ^links index.php?task=links [L]
RewriteRule ^news/item/([0-9]+)/([^/\.]+) index.php?task=news&id=$1 [L]
RewriteRule ^news/page([0-9]+) index.php?task=news&page=$1 [L]
RewriteRule ^members/([^/\.]+)-([^/\.]+)/page([0-9]+)? index.php?task=member_list&sort=$1&order=$2&page=$3 [L]
RewriteRule ^members index.php?task=member_list [L]
RewriteRule ^messages index.php?task=messages [L]
RewriteRule ^submit index.php?task=submit [L]
RewriteRule ^search/([^/\.]+) index.php?task=search&q=$1 [L]
RewriteRule ^search index.php?task=search [L]
RewriteRule ^submit index.php?task=submit [L]
RewriteRule ^r-([0-9]+)?-([0-9]+)? go.php?id=$1&ref=$2 [L]
RewriteRule ^r-([0-9]+)? go.php?id=$1 [L]
RewriteRule ^([^/\.]+)/([0-9]+)/([^/\.]+) index.php?task=view&id=$2&name=$3 [L]
RewriteRule ^news/([^/\.]+) index.php?task=news&name=$1 [L]
RewriteRule ^profile/([^/\.]+) index.php?task=profile&name=$1 [L]
RewriteRule ^news index.php?task=news [L]
RewriteRule ^page/([^/\.]+) index.php?task=view_page&name=$1 [L]  
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/([0-9a-zA-Z'?-]+)/([0-9]+) index.php?task=category&name=$1&sortby=$2&page=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/([^/\.]+) index.php?task=view&name=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+) index.php?task=category&name=$1 [L]


## www reslove ##
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
## www reslove ##

## index reslove ##
Options +FollowSymLinks
RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ http://www.epicwallpaper.net/$1 [R=301,L]
## index reslove ##

1
Además, si alguien puede arreglar al chico malo, ¿podría publicar una respuesta aquí? Gracias
Lucas

Publique el código aquí.
Surreal Dreams

1
Edite su publicación, pegue su código en su publicación, resáltela, presione "CTRL + K" para formatearla como código
Jon Lin

¿Realmente tienes ' o ? permitido en su URI? Una de las RewriteRules (cerca de la parte inferior) lo sugiere. Me preocupa que puedan confundir al servidor incluso antes de que .htaccess pueda procesarlos.
Phil Perry

Respuestas:


194

Justo debajo de la RewriteEngine Onlínea, agregue:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R] # <- for test, for prod use [L,R=301]

para hacer cumplir una política de no barra diagonal.

Para hacer cumplir una política de barra diagonal:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R] # <- for test, for prod use [L,R=301]

EDITAR : comentó las R=301partes porque, como se explica en un comentario:

¡Ten cuidado con esoR=301 ! Tenerlo allí hace que muchos navegadores almacenen en caché el archivo .htaccess indefinidamente : de alguna manera se vuelve irreversible si no puede borrar el caché del navegador en todas las máquinas que lo abrieron. Al realizar la prueba, es mejor ir con simple RoR=302

Una vez que haya completado sus pruebas, puede usar R=301.


4
¡Dios, podría besarte! Trabajó con aplicar una barra inclinada sin arrastre, el otro me dio un error de servidor 500 ¡Gracias, Jon Lin!
Luke

21
La regla sin barra diagonal no funciona si el sitio web está ubicado en un directorio (como example.org/blog/)
Gras Double

7
¡Ten cuidado con eso R=301! Tenerlo allí hace que muchos navegadores almacenen en caché el archivo .htaccess indefinidamente: de alguna manera se vuelve irreversible si no puede borrar el caché del navegador en todas las máquinas que lo abrieron. Al realizar la prueba, es mejor utilizar una simple "R" o "R = 302"
Jonathan Weber

Cuando VirtualDocumentRoot está desactivado, elimine la barra al principio, es decir: en $1lugar de /$1Y, @JonathanWeber, el archivo .htaccess no se sirve, pero el encabezado expires indica a los navegadores cuánto tiempo almacenar en caché un recurso.
twojr

1
@Nrc porque hay otros tipos de asignaciones además de archivos y directorios, y también existe la posibilidad de que una solicitud no se asigne ni a un archivo ni a un directorio, pero que deba reescribirse. Lo negativo asegura que se omita algo que se ha reescrito o que ya se asigna a algo en el sistema de archivos.
Jon Lin

84

Para complementar la respuesta de Jon Lin, aquí hay una técnica sin barra inclinada que también funciona si el sitio web está ubicado en un directorio (como example.org/blog/):

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]


En aras de la integridad, aquí hay una alternativa que enfatiza que REQUEST_URIcomienza con una barra (al menos en los .htaccessarchivos):

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(.*)/$
RewriteRule ^ /%1 [R=301,L] <-- added slash here too, don't forget it

Simplemente no lo use %{REQUEST_URI} (.*)/$ . Porque en el directorio raíz REQUEST_URIes igual a /, la barra inclinada inicial, y sería malinterpretado como una barra inclinada final.


Si está interesado en leer más:

(actualización: esta técnica ahora está implementada en Laravel 5.5)


1
Esta variante en particular es realmente útil, especialmente cuando se utilizan convenciones de URL modernas. Espero que no le importe, lo estoy enviando al repositorio de fragmentos de htaccess .
alexw

1
Esto elimina el problema cuando REQUEST_URI (root) se interpreta como una barra al final que también causa un bucle infinito. Gracias
Ruslan Abuzant

Sí, la respuesta aceptada no se maneja si el sitio web está ubicado en un directorio, pero esta respuesta RewriteCond %{REQUEST_URI} (.+)/$elimina solo una última barra diagonal (por ejemplo, se requieren varias redirecciones de sth /// a sth // a sth / a sth). Para eliminar todas las barras diagonales finales en una redirección, use una mejor soluciónRewriteCond %{REQUEST_URI} (.+?)/+$
mikep

1
Yo también había pensado en esto. Sin embargo, el resultado es correcto, y considerando que es un caso extremo, preferí la simplicidad del código.
Gras Double

@GrasDouble, gracias por haber estado buscando esta solución durante mucho tiempo. Probé innumerables métodos, ¡pero funcionó bien! un gran gracias.

3

Esto es lo que he usado para mi última aplicación.

# redirect the main page to landing
##RedirectMatch 302 ^/$ /landing

# remove php ext from url
# /programming/4026021/remove-php-extension-with-htaccess
RewriteEngine on 

# File exists but has a trailing slash
# /programming/21417263/htaccess-add-remove-trailing-slash-from-url
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*)/+$ /$1 [R=302,L,QSA]

# ok. It will still find the file but relative assets won't load
# e.g. page: /landing/  -> assets/js/main.js/main
# that's we have the rules above.
RewriteCond %{REQUEST_FILENAME} !\.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f 
RewriteRule ^/?(.*?)/?$ $1.php

1
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
## hide .html extension
# To externally redirect /dir/foo.html to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+).html
RewriteRule ^ %1 [R=301,L]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)/\s
RewriteRule ^ %1 [R=301,L]

## To internally redirect /dir/foo to /dir/foo.html
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^\.]+)$ $1.html [L]


<Files ~"^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</Files>

Esto elimina el código html o php si lo complementa. Le permite agregar una barra al final y aparecerá así como la URL sin la barra al final sin pasar por el código 404. Más un poco de seguridad adicional.


Hola, ¿cómo escribirías esto para nginx? Intenté ejecutarlo en un convertidor aquí: winginx.com/en/htaccess pero este resultado me da un bucle infinito:# nginx configuration location / { rewrite ^(.*)$ /%1 redirect; rewrite ^(.*)$ /%1 redirect; rewrite ^/([^\.]+)$ /$1.html break; } location ~ ^.*\.([Hh][Tt][Aa]) { deny all; }
Asle
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.