Htaccess - replace .html with a forward slash - regex

I want to redirect URLs of this form:
/page.html?variable=value&othervar=true&thirdvar=100
To this:
/page/?variable=value&othervar=true&thirdvar=100
So basically I just want to replace the .html in the middle of the URL with a forward slash, but I need to preserve the get string that comes with it. This is what I tried:
RewriteRule ^page.html(.+)$ /page/$1 [L,R=301]
But this doesn't appear to be working for me. I've made similar things work recently but I can't figure out what I'm missing here. Thanks for any input.

Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# external redirect from /example.html to /example
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+([^.]+)\.html [NC]
RewriteRule ^ /%1/ [R=301,L]
# internal forward from /example/ to //example.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule ^(.+?)/?$ /$1.html [L]

Related

.htaccess rewriting on django?

I have a site running on pynton django and I am trying to keep accessible some urls of it, while having a index.html showing.
I've tried to rewrite my .htaccess file but without results. Can anyone help?
Here is my code:
AddHandler fcgid-script .fcgi
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
RewriteRule ^music/preview/listen$/(.*)$ http://example.org/music/preview/listen/$1 [L,R=301]
thanks a lot.
You've got some issues with syntax, it looks like some of your newlines are missing and you have a malformed regex at the end. Try cleaning it up:
AddHandler fcgid-script .fcgi
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !example\.org$ [NC]
RewriteRule ^music/preview/listen/(.*)$ http://example.org/music/preview/listen/$1 [L,R=301]
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
Note that the ^music/preview/listen$/(.*)$ isn't valid, you can't have two $ "end of string" characters.

.htaccess force server to add a trailing slash, except for links with extensions

I had an error in the past "404 Not Found" when writing www.website.com/page instead of www.website.com/page/
And I corrected it by adding the following code to the .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ %{REQUEST_URI}/ [L,R=301]
</IfModule>
But now, it didn't render an xml page, because a trailing slash was added to the link
Example: www.website.com/post-sitemap.xml/
I want to prevent any errors in the future by simply adding a command on the .htaccess so it doesn't add the slash to links ending with: .html .php .xml .css ... etc
Thank you
You can use this rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.[^.]+$
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301]

Apache non www to www badly re writting arrays on URL

we have the following .htaccess configuration:
RewriteEngine on
allow from all
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
# otherwise forward it to index.php
RewriteRule . index.php
RewriteCond %{HTTP_HOST} ^domain1\.domain2\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.domain1\.domain2\.com$
RewriteRule ^(.*)$ "http\:\/\/www\.domain1\.com\/$1" [R=301,L]
RewriteCond %{HTTP_HOST} ^domain1.com$
RewriteRule ^/?$ "http\:\/\/www\.domain1\.com\/" [R=301,L]
Between other things we want to redirect all non-www URLs to the ones with the www.
Everything works fine, except for the pages where the URL is like this:
index?Form%5bplace%5d=Caribbean&Form%5bdestination%5d=Virgin+Islands&Form%5btype%5d=A
When we enter the URL without the www our redirect ends up with the following URL:
index?Form%255bplace%255d=Caribbean&Form%255bdestination%255d=Virgin+Islands&Form%255btype%255d=A
Which gives an 404 error because it is not recognized.
Any idea how to avoid this?
Replace your code with this:
allow from all
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# if a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
# otherwise forward it to index.php
RewriteRule . index.php [L]
RewriteCond %{HTTP_HOST} ^domain1\.domain2\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.domain1\.domain2\.com$
RewriteRule ^ http://www.domain1.com%{REQUEST_URI} [NE,R=301,L]
RewriteCond %{HTTP_HOST} ^domain1\.com$
RewriteRule ^/?$ http://www.domain1.com/ [R=301,L]
What's happening is that the % symbol is getting escaped to %25.
You can avoid this using the NE flag on your rules

Remove 'index.php' from URL with .htaccess

I've been trying all sorts of solutions from this site and none seem to work. I'm currently hosting with hostgator. This is my current .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
<IfModule mod_suphp.c>
suPHP_ConfigPath /home/user/php.ini
<Files php.ini>
order allow,deny
deny from all
</Files>
</IfModule>
This is in the root folder of my site. I have also tried adding a ? after index.php and no luck. Does anyone know why this isn't working?
This is the code you can use in your .htaccess (under DOCUMENT_ROOT) to remove index.php from URI:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ %1 [R=301,L]
Symfony 2 has an excellent solution:
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by apache
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/index.php [L]
This accomplishes the following:
RewriteBase is not necessary (useful when the site is in a subdirectory beneath the web root)
index.php is removed if present
The request is routed to the correct index.php with the full query string from the original request
Note that the line:
RewriteRule ^(.*) - [E=BASE:%1]
is responsible for setting the %{ENV:BASE} variable for later on. Refer to Apache documentation on E|env flag.
I tried this and works fine:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
Exceptions
If your site’s system directory (/system/) has been renamed and is still accessible by URL, modify the RewriteCond line above:
RewriteCond %{REQUEST_URI} !/newdirectoryname/.* [NC]
If you are running EE from a sub-directory rather from the root of your domain (e.g. http://example.com/myeesite/ instead of http://example.com/), just remove the slash preceding index.php in the RewriteRule line above, like so:
RewriteRule ^(.*)$ index.php/$1 [L]
If you are running EE from a sub-directory and it still doesn’t work after removing the slash, you may need to specify the sub-directory in your rewrite rule. For example, if your sub-folder is named testing, change:
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
To:
RewriteRule (.*?)index\.php/*(.*) testing/$1$2 [R=301,NE,L]
And change:
RewriteRule ^(.*)$ /index.php/$1 [L]
To:
RewriteRule ^(.*)$ testing/index.php/$1 [L]
If your host requires forcing query strings, try adding a question mark following index.php in the RewriteRule line above, like so:
RewriteRule ^(.*)$ /index.php?/$1 [L]
To remove index.php from urls on apache2.4 you can use the following rule :
RewriteEngine on
RewriteRule ^index\.php/(.+)$ /$1 [L,R]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !index\.php /index.php%{REQUEST_URI} [L,END]
This will change the uri
/index.php/foobar
to
/foobar
This rule will return an internal server error for lower versions of apache as they don't support the END flag. Please see the anubhava's answer above that works almost on all versions.
I've been compelled to join stack overflow.com today to comment here as the answer has solved a long term problem I've had with a Zend Framework website. I've worked on the website around 3 1/2 years and during that time I discovered that it didn't handle index.php correctly and this causes webmaster tools to see duplicate titles etc.
I decided to search again today for a solution, one of many times attempted.
This is the one (the last answer shown above) that solves my problem.
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
As an example. this is what it achieves for me.
http://www.domainname.co.uk/index.php/categories/url-name.html
becomes
http://www.domainname.co.uk/categories/url-name.html
Thank you to everyone who contributed to the original question as it lead to the answer and solution above.
Extra Note: I have other rewrite commands that handles the other aspects but those on their own didn't fix the index.php and the only time this has been fixed is by using.
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
I only hope it helps others whether its ExpressionEngine or Zend Framework, in the future.

HTACCESS redirection with a word replacement in url

I'm having trouble with this reg expression which i belive is correct, but it is not working.
What im trying to do is redirect bunch of urls containing a specific string like this:
http://www.example.com/**undesired-string**_another-string to http://www.example.com/**new-string**_another-string
and
http://www.example.com/folder/**undesired-string**/another-string to http://www.example.com/folder/**new-string**/another-string
So i have this code in the .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule (.+)+(undesired-string)+(.+) $1new-string$2 [R=301,L]
</IfModule>
This should replace ANY undesired-string in any url to new-string, but it is not working, any idea why ?
Thank you
Marwen: Try this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)undesired-string(.*)$ yoursite.com/$1new-string$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
RewriteCond %{HTTP_HOST} !^www.yoursite.com$ [NC]
RewriteRule ^(.*)$ yoursite.com//$1 [L,R=301]
</IfModule>
In your 'updated' code in the comments above, you had it applying the rewrite condition to the undesired-string... So if the actual file or directory was valid it would not rewrite...
Doing this though will always rewrite the undesired-string with new-string - even if its a file name... If that is fine or what you want then all you had to do was move your rewrite conditions to below the rewrite rule...
also.. Just an fyi.. If everything is on yoursite.com you dont need to list yoursite.com
i.e.
yoursite.com/$1new-string$2
just needs to be
/$1new-string$2
which does the same thing: rewrites to the base directory of yoursite.com
now if they are going from mysite.com to yoursite.com then you woulud want to include the domain name because you are redirecting across domain names
Edit: You may also want to use:
[QSA,L,R=301]
instead of just [L,R=301]
Your regex is not really correct. Try:
RewriteRule ^(.*)undesired-string(.*)$ $1new-string$2 [R=301,L]
Or if this doesn't work, try:
RewriteRule ^(.*)undesired-string(.*)$ http://yoursite.com/$1new-string$2 [R=301,L]
Explanation:
^ marks the beginning; $ marks the end; the first (..) goes to $1, the second (..) goes to $2 and so on; * is 0 or more chars; + is 1 or more chars.
To answer my own question. Laravel already redirects the trailing slashes. Problem was that Laravel was installed into a sub-directory. I added the location of the sub-directory to the redirect. My location in this case is: "/lumen/public/". See the fixed htaccess below.
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /lumen/public/$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>