Remove trailing slash if not a directory with apache - apache

I have the following rewrite rules:
#remove the www.
RewriteCond %{HTTP_HOST} ^www.website.co.uk$ [NC]
RewriteRule ^(.*)$ http://local.website.co.uk/$1 [R=301,L]
#this removes php extention
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
# stops you accessing url with.php
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^.?\ ]+)\.php
RewriteRule ^([^.]+)\.php(/.+)?$ /$1%{PATH_INFO} [R=301]
I want to add in a rule that removes the trailing slash if someone tries to access site with one.
eg
website.co.uk/cheese/ should redirect to /cheese
as you can see I have a rule that redirects ursl with the .php extention, not sure where to begin.
I do have directory in the root folder which I do not wish to remove the trailing url, but I can add a ignore rule for those.
Cheers

Make the change below to your .htaccess file
RewriteEngine on
RewriteBase /
#existing rule
#remove the www.
RewriteCond %{HTTP_HOST} ^www.website.co.uk$ [NC]
RewriteRule ^(.*)$ http://local.website.co.uk/$1 [R=301,L]
#new Rule
#if its not a directory
RewriteCond %{REQUEST_FILENAME} !-d
#and it has a trailing slash then redirect to URL without slash
RewriteRule ^(.+)/$ /$1 [L,R=301]
# rest of your existing rules go here

Related

.htaccess - remove everything after third slash in path

On my website, I only use 3 slashes in my URL path:
https://example.com/this/isatest/
Right now I use .htaccess which makes it possible (as a side effect) to add as many stuff on the URL as you like:
https://example.com/this/isatest/hipperdihopperdus/pizza/bacon/with/cheese
I'd like to automatically remove everything after "isatest" while keeping the trailing slash using .htaccess.
This is what my .htaccess currently looks like:
Options -Indexes
Options +FollowSymLinks
RewriteEngine on
# 301 Redirect all requests that don't contain a dot or trailing slash to
# include a trailing slash
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.
RewriteRule ^(.*) %{REQUEST_URI}/ [R=301,L]
RewriteCond %{THE_REQUEST} /index\.html [NC]
RewriteRule ^index\.html$ /? [R=301,L,NC]
RewriteRule ^listen/$ /console/ [NC,L]
# Rewrites urls in the form of /parent/child/
# but only rewrites if the requested URL is not a file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [L,QSA]
How can I achieve this?
As your first rule, after the RewriteEngine directive, you can do something like the following:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+/[^/]+/). /$1 [R=302,L]
This checks if there is anything else (the dot) after two path segments and a slash, and redirects to removed "anything else".
Note that this is a 302 (temporary) redirect. Only change this to a 301 (permanent) redirect - if that is the intention - once you have confirmed that it works OK. This is to avoid the browser caching erroneous redirects whilst testing.
UPDATE: It may be more efficient to simply avoid redirecting files that end in a recognised file extension. Or perhaps exclude known directory location(s) of your static resources. For example:
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|png|gif)$ [NC]
RewriteRule ^([^/]+/[^/]+/). /$1 [R=302,L]
OR,
RewriteCond %{REQUEST_URI} !^/static-resources/
RewriteRule ^([^/]+/[^/]+/). /$1 [R=302,L]
You can add this rule just below RewriteEngine On line:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+/[^/]+/).+$ /$1 [R=301,L,NE]

Rewrite condition in .htaccess for slash and non slash version throws status code 500

We are trying to set up a redirection rule in .htaccess so our every URL with slash in the end is redirected to a non slash version.
We have implemented this code which i believe should do the work:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
What is happening now is, when I try to visit the slash version, I get 500 status code. Here is the URL of the website: plicnivek.cz. Is our .htaccess rule implemented correctly?
Your rule is incorrect as it also rewrites non-existent files directory to PHP. You can use the following rule to remove trailing slash and rewrite php extension.
RewriteEngine on
#remove traling slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ /$1 [R=301,L]
#remove .php
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.+)/?$ /$1.php [L]

.Htaccess - Remove trailing slash, whilst all pages still go to index.php

I've searched over previously asked questions but none have the same problem as me. I'm wanting to remove the trailing slash, whilst still sending all pages to index.php (or if the file actually exists, use that.)
I'd like a solution that I don't have to fiddle with between server and localhost.
So localhost/pages/to/file/ and http://example.com/pages/to/file/, go to ... /pages/to/file
My current htaccess file:
RewriteEngine on
# removes www.
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1%{REQUEST_URI} [R=301,QSA,NC,L]
# if file exists, ignore the index.php re-write
RewriteCond %{REQUEST_FILENAME} !-f
# send everything to index.php
RewriteRule . index.php
Give the following a try:
RewriteEngine on
# Remove the trailing slash, if not in a directory
# DirectorySlash off can be used instead.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Remove www. (generic method with HTTPS support)
RewriteCond %{HTTP_HOST} ^www\.
RewriteCond %{HTTPS}s ^on(s)|off
RewriteCond http%1://%{HTTP_HOST} ^(https?://)(www\.)?(.+)$
RewriteRule ^ %1%3%{REQUEST_URI} [R,L]
# Send everything (except existing files) to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
If this works for you, change the R flag to R=301 to make the redirect permanent.
You can add an extra condition to your existing rule to remove www and remove any trailing slash in that rule too.
RewriteEngine on
# removes www. and trailing slash
RewriteCond %{REQUEST_URI} /$ [OR]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*?)/?$ http://%1/$1 [R=301,QSA,NC,L]
# if file exists, ignore the index.php re-write
RewriteCond %{REQUEST_FILENAME} !-f
# send everything to index.php
RewriteRule . index.php
See the documentation for clarification.
Have a separate rule for removal of trailing slash:
RewriteEngine on
# removes www.
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,NE,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{THE_REQUEST} \s/+(.*?)[^/][?\s]
RewriteRule [^/]$ %{REQUEST_URI}/ [L,NE,R=301]
# if file/directory exists, ignore the index.php re-write
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# send everything to index.php
RewriteRule . index.php [L]

Add trailing slash to url using .htaccess

I would like to add trailing slash for deep level of my urls
So let's say i have this url
mysite.com/work
when user access that url, i want to be redirected to:
mysite.com/work/ (this i want to happen)
But i want this only deep levels, not for .html pages
mysite.com/testing.html/ (i don't want this to happen)
I have this .htaccess rule, but this add trailing slash to my .html pages also. i don't want that.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]
Any help?
You can use this rule for adding trailing slash only for non-files:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{THE_REQUEST} \s/+(.*?)[^/][?\s]
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301,NE]

How to remove multiple trailing slashes?

Here are my rewrite rules:
###########
# Rewrite #
###########
# Settings
RewriteEngine On
RewriteBase /
# Cache Busting
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} "^(.+)\.\d+\.(css|js)$" [NC]
RewriteRule "^.*$" "/%1.%2" [L]
# No Index
RewriteCond %{THE_REQUEST} "\ /.*index\.php.*\ " [NC]
RewriteRule "^(.*)index\..+$" "/$1" [L,NC,R=301]
# No Question Mark
RewriteCond %{THE_REQUEST} "\ /[^?]*\?\ "
RewriteRule "^(.*)$" "/$1?" [L,R=301]
# WWW
# RewriteCond %{HTTP_HOST} !"^(?:static|www)\.(.+)$" [NC]
# RewriteCond %{HTTPS}s "^on(s)|"
# RewriteRule "^(.*)$" http%2://www.%1/$1 [L,R=301]
Everything works fine (any suggestion to improve performances or for better regexps is welcome, anyway) but I'm experiencing a weird situation and I can't understand if it's produced by my rewrite rules or by a default Apache behavior.
If my URL ends with a "/", I can append as many slashes as I want without it being rewritten.
For example, if in my address bar I insert the following:
http://[MY-HOST-NAME]////////////////////////////
All those slashes are not being removed. And I'm still seeing my index.php page.
If I insert the following address:
http://[MY-HOST-NAME]/members///
All those multiple slashes are not being removed and I can see my members index.php page.
And so on...
Can someone help me please? Many thanks!
RewriteCond %{THE_REQUEST} //
RewriteRule .* $0 [R]
# rule 1: remove multiple leading slashes (directly after the TLD)
RewriteCond %{THE_REQUEST} \s/{2,}
RewriteRule (.*) $1 [R=301,L]
# rule 2: remove multiple slashes in the requested path
RewriteCond %{REQUEST_URI} ^(.*)/{2,}(.*)$
RewriteRule (.*) %1/%2 [R=301,L]
RewriteEngine on
RewriteBase /
#existing rule
#remove the www.
RewriteCond %{HTTP_HOST} ^www.website.co.uk$ [NC]
RewriteRule ^(.*)$ http://local.website.co.uk/$1 [R=301,L]
#new Rule
#if its not a directory
RewriteCond %{REQUEST_FILENAME} !-d
#and it has a trailing slash then redirect to URL without slash
RewriteRule ^(.+)/$ /$1 [L,R=301]
# rest of your existing rules go here
Gerbens answer works well for .htaccess but not so much for global config.
This one removes all the slashes before sending the redirect.
# if match set environment variable and start over
RewriteRule ^(.*?)//+(.*)$ $1/$2 [E=REDIR:1,N]
# if done at least one. redirect with 301
RewriteCond %{ENV:REDIR} 1
RewriteRule ^/(.*) /$1 [R=301,L]