htaccess redirect and rewrite rules conflicting - apache

I want to rewrite all requests to index.php?r=
So that /sth becomes /index.php?r=sth
I have applied this rule that works:
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteCond %{REQUEST_URI} !^.*\.(jpg|css|js|gif|png|pdf|php)$ [NC]
RewriteRule ^(.+)$ index.php?r=$1 [L]
However I want to also have redirects such as
Redirect 301 /sth /sth-new
What happens is that it works but the url becomes:
/sth-new?r=sth
Do you have any solutions - suggestions about why this is happening?
How can I implement a global rule and also have simple redirects?

You can do it like this:
RewriteRule ^sth/?$ /sth-new? [L,R=301]
RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteCond %{REQUEST_URI} !\.(jpg|css|js|gif|png|pdf|php)$ [NC]
RewriteRule ^(.+)$ index.php?r=$1 [L]
You should keep external redirect rules before your internal rewrite rules.

Related

Htaccess Redirects - Combine many rules in one single redirect

I am trying to combine more rules in a single redirect, right now I have many rules and many redirects, like in the picture attached, but for SEO purpose this is not a good behavior.
The story is this: I have an old url, which doesn't exist anymore and a new one, where I want to be redirected. If the requested url doesn't have www. and https then I want to add them.Also if the url has an slash at the end, I want to remove it.
All is working right now, but in many steps.
This is what I have in my .htaccess file:
301 redirect from old url to the new one with www.
RewriteRule ^source1/source2$ https://www.domain.com/destination1/destination2 [L,R=301]
Remove the slash from the end of URL
RewriteCond %{REQUEST_URI} !^/system [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)/$ /$1 [R=301,L,QSA]
Redirect to https
#-----------------redirect to https-----------------
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^www.domain.com(.*)$ [NC]
RewriteRule (.*) https://www.domain.com%{REQUEST_URI} [L,R=301]
I use all of these rules inside this directive:
<IfModule mod_rewrite.c>
Have it like this to avoid multiple 301 for SEO purpose:
# specific redirects
RewriteRule ^source1/source2/?$ https://www.domain.com/destination1/destination2 [L,R=301,NC]
# Remove the slash from the end of URL
RewriteCond %{REQUEST_URI} !^/system [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ https://www.domain.com/$1 [R=301,L,NE]
#-----------------redirect to https-----------------
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.domain.com%{REQUEST_URI} [L,R=301,NE]
Make sure to clear your browser cache completely before testing this change.

Simplifying a series of redirections using mod_rewrite

My client has an SSL cert for MAINSITE.com but gets a lot of traffic via OTHERSITE.com.
Client would like all visitors to use HTTPS all the time.
So my rules start out by checking for OTHERSITE.com and redirecting to https://MAINSITE.com if found.
Then I check to see if we are using HTTPS and redirect if not.
Then there are a series of rules aimed at using the sub-directories in the URL to pull content and load templates.
My question is whether these rules are as efficient as the should be and if anyone sees issues with how they are written? I'm no mod_rewrite expert.
Plus we have had a few users who reported IE bailing out on them when the WWW version of the URL was loaded but I can't see why? Any advice?
ErrorDocument 404 /index.php
RewriteEngine on
RewriteCond %{HTTP_HOST} OTHERSITE.com [NC]
RewriteRule ^(.*)$ https://MAINSITE.com/$1 [L,R=301]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteBase /
RewriteRule ^products - [L,NC]
RewriteRule ^sauces$ /sauces.php?sauce=our-hot-sauce [L,QSA]
RewriteRule ^sauces/([^/\.]+)/?$ /sauces.php?sauce=$1 [L,QSA]
RewriteRule ^recipes/([^/\.]+)/?$ /recipes.php?cat=$1 [L,QSA]
# user has cleared recipe name but not cat AND left trailing slash
RewriteRule ^recipe/([^/\.]+)/$ /recipes.php?cat=$1 [L,QSA]
# has sauce/cat and recipe name
RewriteRule ^recipe/([^/\.]+)/([^/\.]+)/?$ /recipe.php?cat=$1&rec=$2 [L,QSA]
# user has cleared recipe name but not cat
RewriteRule ^recipe/([^/\.]+)$ /recipes.php?cat=$1 [L,QSA]
RewriteRule ^([^/\.]+)/?$ /page.php?page=$1 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2&subsub=$3 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2&subsub=$3&subsubsub=$4 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2&subsub=$3&subsubsub=$4&subsubsubsub=$5 [L,QSA]
Rest of the rules like fine but first 2 301 rules can be combined into one:
RewriteCond %{HTTP_HOST} ^(www\.)?OTHERSITE\.com$ [NC,OR]
RewriteCond %{HTTPS} off
RewriteRule ^ https://MAINSITE.com%{REQUEST_URI} [L,R=301,NE]

htaccess mod rewrite rule appending url params

I have a gallery script that works very simply.
The index page (php) loads all pictures in thumbnail view based on the url params. I'm trying to use the rewrite rules to mask the urls so they look nicer, but I'm having an issue.
The index page takes a=gallery&name={name of gallery}
The rewrite is working to the extent that it's rewriting the urls to /gallery/{name of gallery}
The problem is I'm getting /gallery/{name of gallery}/?a=gallery&name={name of gallery} which is obviously not desired and redundant anyway.
Here's my rule, I've been messing with this and I'm tired to going over the docs and just want this finished.
# enables rewrite engine
RewriteEngine on
# we always direct requests to the www subdomain
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
# some url rewriting
RewriteRule ^([^/\.]+)$ ?a=$1 [L]
RewriteRule ^([^/\.]+)/$ ?a=$1 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)$ ?a=$1&name=$2 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/$ ?a=$1&name=$2 [L]
Edit: added complete htaccess file...
Try it this way and see how it works for you.
# enables rewrite engine
RewriteEngine on
# we always direct requests to the www subdomain
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_URI} ^/gallery
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+) index.php?url=$1&name=$2 [PT,L]
RewriteCond %{REQUEST_URI} ^/gallery
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+) index.php?url=$1 [PT,L]

Redirect not working for complex rewrite rules (.htaccess)

I'm trying to make a redirect from a non-www version of the link to the www one. Its working fine for something like http://mywebsite.com but it fails for a request like http://mywebsite.com/artists/metallica/ or even a complex one. The whole .htaccess file is bellow. Any clues?
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*).html
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://mywebsite.com/$1/ [L,R=301]
RewriteRule ^artists/([^/-]+)-p([^/]+)/$ /artists.php?l=$1&p=$2 [QSA,L]
RewriteRule ^artists/([^/]+)/$ /artists.php?l=$1 [QSA,L]
RewriteRule ^submit/$ /submit.php [QSA,L]
RewriteRule ^users/$ /users.php [QSA,L]
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ http://www.mywebsite.com/$1 [R=301,L]
Try this rule:
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
But make sure that you put this rule in front of those rules that just do an internal rewrite. Otherwise an already internally rewritten rule might get redirected externally.

htaccess problems with redirect for no www

I've been trying everything to manage a redirect from www.domain.com to domain.com,
but nothing seems to work for me. I always get a redirect loop - and I've tried various things I found here or on Google.
So here is my .htaccess, maybe someone could help me figure out what I can do to redirect correctly or if there is something wrong in here.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
# Redirect all to .php
# Example: example.com/hello -> example.com/hello.php
RewriteRule ^(.*)$ $1.php [L,R=301]
# show example.com/index.php always as example.com/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://example.com/ [R=301,L]
Thank you so much!
I've already spent so much time trying to figure this out.
You have a rule that always matches, which is responsible for the infinite redirection. I've updated your ruleset below to fix that problem and perform the redirection you mentioned at the top of the answer. Let me know if this does what you expect.
RewriteEngine On
# Redirect www.example.com to example.com
RewriteCond %{HTTP_HOST} ^www [NC]
RewriteRule ^.*$ http://example.com/$0 [R=301,L]
# This performs an external redirection? Is that what you want?
# Don't do the rewrite if we're already pointing at a file, otherwise we'll
# just redirect over and over because .* matches what we redirect to, too
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !\.php$
RewriteRule ^.+$ $0.php [L,R=301]
# show example.com/index.php always as example.com/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://example.com/ [R=301,L]
The answer is Apache documentation, the documentation tell how to force usage of www. You just have to reverse the example.
RewriteCond %{HTTP_HOST} !^example\.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://example.com/$1 [L,R]