Ignore trailing slash with Apache Rewrite - apache

I'm using mod_rewrite to redirect like so:
RewriteRule (work)/?$ $1.php [L]
This sends any URL ending in /work or /work/ to work.php
The problem is, when a trailing slash is included, it treats it as a directory, and not the file that it really is. This, of course, breaks all of my relative paths in the file.
I don't mind having a slash in the URL, but is there any way to use Apache to ignore the trailing slash, and treat the URL as a file, just as it would without the slash?

Since you don't want the URL to look like www.domain.com/work/ here's what you can do:
RewriteEngine On
RewriteRule ^work/$ http://www.domain.com/work%{REQUEST_URI} [R=301,L,NC]
RewriteRule (work)$ $1.php [L,QSA,NC]
This will redirect /work/ to /work and /work/?page=main to /work?page=main

Related

Remove trailing slash after directory with htaccess

I want to remove / when I want to get access to the index file in a subdirectory folder. For example: www.example.com/test/dashboard/ to www.example.com/test/dashboard.
I tried this:
RewriteEngine On
# Remove "/" to "/dashboard"
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule (.*) $1%1/ [L]
It will not remove the / from the subdirectory.
Can you please show me an example of how I can remove the / with .htaccess when I want to get access to my subdirectory?
# Remove "/" to "/dashboard"
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule (.*) $1%1/ [L]
This doesn't "remove" anything. In fact, it will append a trailing slash to the end of the URL-path and query string, which seems a bit random?
However, you can't simply remove the trailing slash that occurs after a physical directory in the URL-path, since mod_dir will try to append it with a 301 redirect in order to "fix" the URL.
You can prevent mod_dir from appending the trailing slash with the DirectorySlash Off directive. However, you then need to manually append the trailing slash to the directory with an internal rewrite in order to correctly serve the "index file" (ie. the DirectoryIndex document).
I'm assuming you are linking to the directory without a trailing slash in your internal links.
Try the following instead:
# Disable directory listings (mod_autoindex)
Options -Indexes
# Prevent mod_dir appending trailing slash to directories
DirectorySlash Off
RewriteEngine On
# Rewrite the URL to append a trailing slash to directories (internally)
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*[^/])$ $1/ [L]
A request for /dashboard (no trailing slash) that maps to a physical directory will be internally rewritten to /dashboard/, which will allow the "index file" to be served (by mod_dir also).
For security reasons, you need to ensure that directory listings (mod_autoindex) are disabled, otherwise, directory listings could potentially be generated for directories even when they contain a directory index document. See the security warning in the Apache docs under the DirectorySlash directive.
You need to ensure that your browser cache is cleared before testing since the 301 (permanent) redirect by mod_dir (to append the trailing slash) will have certainly been cached by the browser.
Remove the trailing slash (optional)
You could implement a canonical redirect to actually "remove" the trailing slash from the URL, should there be any requests from third parties (or search engines) that include the trailing slash. (It should already be removed on all your internal links, so this is not required to make your site "work", however, it could be required for SEO to avoid potential duplicate content.)
I'm assuming you don't want the trailing slash on any URL.
You should add the following "redirect" before the rewrite above, immediately after the RewriteEngine directive.
# Remove the trailing slash, should it appear on any 3rd party requests
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)/$ /$1 [R=301,L]
The check against the REDIRECT_STATUS environment variable is to ensure we do not redirect the already written request (that appends the trailing slash) by the later rewrite, during the second pass of the rewrite engine. Alternatively, you could use the END flag (Apache 2.4) on the later rewrite.

Trailing slash mod_rewrite rule for certain subfolders

I am trying to get a trailing slash mod_rewrite rule to work for only certain subfolders.
I have article URLs like ////. For example an article URL may be /news/role-playing-games/new-roleplaying-game-released/. Sometimes, for whatever reason, people try the URLs without the trailing slash and they get a 404. I would like instead for apache to add a trailing slash to only the URLs that match certain subfolders.
I tried this rule, but it does not work.
RewriteCond %{REQUEST_URI} ^/(news|reviews|tutorials|guides)/(.*)$
RewriteRule ^(.*)$ /$1/ [L,R=301]
Can anyone tell me what I am doing wrong?
Thanks in advance.
Try
RewriteRule ^((news|reviews|tutorials|guides)/[^/]+/[^/]+)$ $1/ [L,R=301]
I assumed that the url structure you gave is the only one.

Htaccess remove string from URL behind last slash

Looking for solution how to remove anything behind URL last slash.
example output URL:
http://example.com/pictures/123/category-name/
problems to avoid for this URL:
http://example.com/pictures/123/category-name/blah.html
http://example.com/pictures/123/category-name/blah/blah.html
http://example.com/pictures/123/category-name/blah/blah/blah.html
http://example.com/pictures/123/category-name/blah/
http://example.com/pictures/123/category-name/blah
So far i have this:
RewriteRule ^([A-Za-z0-9-]+)/([0-9]+)/category-name/$ $1/$2/category-name/ [R]
RewriteRule ([A-Za-z0-9-]+)/([0-9]+)/category-name/(.*)$ category.php?VarA=$1&VarB=$2
it works for output URL and the URL with anything behind pattern. Problem is that it doesn't rewrite (redirect) to output URL if anything is behind last slash.
I'd personally use logic which is straight-forward like this:
#redirect to canonical url if no ending slash
RewriteRule ^([A-Za-z0-9-]+)/([0-9]+)/category-name$ $1/$2/category-name/ [R,L]
#redirect to canonical url if anything behind slash
RewriteRule ^([A-Za-z0-9-]+)/([0-9]+)/category-name/(.+)$ $1/$2/category-name/ [R,L]
#rewrite to PHP file if visiting the canonical url
RewriteRule ^([A-Za-z0-9-]+)/([0-9]+)/category-name/$ category.php?VarA=$1&VarB=$2 [L]

Remove double slash at the begining of URL path

Due to moving of a site, the old hoster created a redirect to the new location. However, there is a leading slash / in the redirection and the former hoster is not able/willing to fix it. So I end up with all the redirects coming in like this:
http://sub.domain.com//path/to/file.html
So I tried to remove the leading slash:
using mod_alias
RedirectMatch 301 ^//(.*)$ http://sub.domain.com/$1
using mod_rewrite
RewriteEngine on
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(/{2,})(.*)$
RewriteRule . %1/%3 [R=301,L]
Neither works. The latter removes multiple slashes inside the path, but not at the beginning.
There are already questions regarding slash removing, but they don't solve this problem:
Issue In Removing Double Or More Slashes From URL By .htaccess
.htaccess - how to remove repeated characters from url?
Does Apache somehow treat this case differently?
How do I get rid of one of the leading slashes?
The Problem
The point is that Apache 2 do not include leading slashes in the Requested URI, so you can't do this:
RewriteRule ^/+(.*)$ /$1 [R=301,L]
or that:
RewriteCond %{REQUEST_URI} ^/+(.*)$
RewriteRule ^.*$ /%1 [R=301,L]
what workes grat for any other kind of redirects or rewrites.
The Solution
But what you can do is to use the the Apache request variable that usually looks something like this:
GET /some-page HTTP/1.1
With this in mind we can do the following:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,7}\s//+(.*)\sHTTP.*$
RewriteRule ^.*$ /%1 [R=301,L]
So all leading slashes will be reduced to the one that that we need.
I tested this positive on apache 2.4
This code work for me
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/+(.*?)/{2,}([^\s]*)
RewriteRule ^ %1/%2 [R=301,L,NE]
The First / is Implied
Try this:
RewriteEngine on
RewriteRule ^/(.+) $1 [R=301,L,B,NE]
Why?
To match two slashes at the beginning of the path, in htaccess, we don't need to look for two slashes—just one—because the first slash is assumed. For instance, if you wanted to match example.com/pasta, your match rule would be ^pasta$, not ^/pasta (which would only match on example.com//pasta).
This is different from httpd.conf, where you would need to specify both slashes.
Confusing, but that's how it works.

301 Redirects: Ignore Trailing Slashes and index.html

My client's existing site used URLs that could be in any one of these combinations:
site.com/canada/mountain_rail
site.com/canada/mountain_rail/
site.com/canada/mountain_rail/index.html
site.com/canada/mountain_rail/index.html/
Any URL might (or might not) have a trailing slash, and might (or might not) end with index.html. It's a bit of a nightmare.
I'm trying to write a 301 redirect that can take any one of those strings and redirect to a different page on their new site. What I have so far is this:
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^canada/mountain_rail$ /canada/mountain-rail-vacations? [R=301,NE,NC,L]
This works fine with URLs like site.com/canada/mountain_rail, but site.com/canada/mountain_rail/ or site.com/canada/mountain_rail/index.html don't work and just return a 404.
Can anyone assist with this? I'm a bit of a beginner at Rewrite rules.
Thanks!
Make trailing slash optional:
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^canada/mountain_rail(?:/index\.html)?/?$ /canada/mountain-rail-vacations? [R=301,NE,NC,L]