HTACCESS RewriteCond without messing up localhost
I have the following bunch of domains:
- myDomain.de
- myDomain.com
- myDomain.co.za
- myDomain.org
- myDomain.com
- myDomain.com.na
What is the shortest way to write in the htaccess, to make ALL domains...
- Redirect to https://www.myDomain.com. I.e. Regardless of the domain that is entered, it will add www AND redirect to https, and
- Still wor开发者_高级运维k on my localmachine (so that if someone types in http://localhost/site/src that it won't redirect to the www sites?
Let's see if this works:
RewriteEngine On
# Check if the host name contains a . (localhost won't)
# Check if the host name starts with www
# Check if the host name ends with .com
# Check if the connection is secure
RewriteCond %{HTTP_HOST} \.
RewriteCond %{HTTP_HOST} !=svn.myDomain.com
RewriteCond %{HTTP_HOST} !^www [OR]
RewriteCond %{HTTP_HOST} !\.com$ [OR]
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://www.myDomain.com/$0 [R=301,L]
A foolproof solution:
# If not on www., redirect to www. on SSL
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
RewriteCond %{HTTP_HOST} !^www
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
# If not on SSL(ish), redirect to SSL
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
Let's break it down.
If the requesting client is NOT on the reserved localhost IP address
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
Typically, when accessing a locally hosted website, the IP address of the client is 127.0.0.1
. Every now and then, it's 127.0.1.0
. But the entire 127.x.x.x
range is reserved for local, so I'm checking against all of them, just in case you have a fun setup.
This is safer than checking for localhost
or checking for the existence of a .
-- it also allows you to edit your /etc/hosts
file to point www.myDomain.com
to your localhost for more realistic testing. Or, if you're like me, you have a domain nomenclature, like nathan.dev.mydomain.com
or mydomain.com.dev
.
Checking for "www."
RewriteCond %{HTTP_HOST} !^www\.
If the domain doesn't (!
= doesn't) start with (^
= start with) www.
...
Port 443 vs HTTPS environment variable
RewriteCond %{SERVER_PORT} !^443$
Using port 443 is a safer check as the HTTPS environment variable cannot be guaranteed when working with load balanced servers.
The actual rule
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
This will force everything to use the "www." equivalent of that domain. E.g. mydomain.com becomes www.mydomain.com; mydomain.de becomes www.mydomain.de.
As an alternative, you can use the following rule which forces every domain to redirect to the www.
as well as the .com
:
RewriteRule ^(.*)$ https://www.myDomain.com/$1 [R=301,L]
Two condition/rule blocks, not one.
Using two blocks, you can have a little more clarity as to what exactly is going on. In addition, writing this as one block simply won't work if the requirement is to allow the use of any TLD. You could combine them into one block, if you used the alternate rule above. The one-block alternate would look like this (notice the addition of [OR]
):
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
RewriteCond %{HTTP_HOST} !^www [OR]
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(.*)$ https://www.myDomain.com/$1 [R=301,L]
It's also worth noting that the two-block solution sometimes results in two redirects, but if you leave it in the exact order, you'll reduce redirects.
Example: With the current order of rules, if a client requested http://mydomain.com
, the first block would apply (no www.
exists) and will redirect to https://www.mydomain.com
. However, if you flipped the order, then the server would first detect the lack of SSL and the client would be redirected to https://mydomain.com
, then the server would detect the lack of www.
and serve an additional redirect to https://www.mydomain.com
. tl;dr: Don't change the order. :)
Happy hacking!
RewriteCond %{HTTP_HOST} \.
The localhost check is working perfectly for me without breaking the redirect on my remote site, I was looking for this solution too. I just have to remember to enter "localhost" in my browser and not 127.0.0.1 or 192.168.x.x but that's not a constraint. Great solution.
精彩评论