.htaccess redirect www to non-www with SSL/HTTPS
Asked Answered
P

9

81

I've got several domains operating under a single .htaccess file, each having an SSL certificate.

I need to force a https prefix on every domain while also ensuring www versions redirect to no-www ones.

Below is my code; it doesn't work:

RewriteCond %{HTTP_HOST} ^www.%{HTTP_HOST}
RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI}/$1 [R=301,L]

What I want to achieve is to: redirect something like https://www.example.com to https://example.com.

What am I doing wrong and how can I achieve it?

Payment answered 25/9, 2009 at 15:59 Comment(1)
Hope this helps, it also explains which is best for SEO too. wpza.net/redirect-wordpress-to-https-using-htaccess-fileLani
S
116

www to non www with https

RewriteEngine on

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

RewriteCond %{ENV:HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Slate answered 3/3, 2015 at 11:46 Comment(5)
"RewriteRule ^(.*)$ http://%1/$1 [R=301,L]" was changed to "RewriteRule ^(.*)$ https://%1/$1 [R=301,L]" (by @KenVerhaegen) otherwise "it would first redirect to non-http, and then to https... so now we can avoid the possibly triggered second redirect."Scevor
Really simple and match, this should also the right answer for this questionFaldstool
no matter what i try, it doesnt work for Safari and Firefox. Chrome is ok. any solution would help - i have certificate only for example.com - not for example.comIntellection
@KalpeshPopat: This was probably because your browser cache kept the info where to go when you enter the URL. As soon as the DNS/browser cache update, it will work.Regarding
is this answer working in 2021? I tried but I am getting the error "The page isn’t redirecting properly" in firefox.Baruch
S
63

Ref: Apache redirect www to non-www and HTTP to HTTPS

http://example.com

http://www.example.com

https://www.example.com

to

https://example.com

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

If instead of example.com you want the default URL to be www.example.com, then simply change the third and the fifth lines:

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [L,NE,R=301]
Strasser answered 19/12, 2017 at 16:9 Comment(7)
For redirecting to Non-WWW URL with HTTPS this answer with the first section is absolutely perfect and works fine for me.Charlottcharlotta
After this many years still your answer is charm.Aron
This worked. But make sure this is on the top of your .htaccess file and not below, because other code may overwrite it.Hey
It won't redirect example.com to example.comAutoicous
Where should i add my domain name in this code : RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]. What is the meaning for %1 and {REQUEST_URI}?Cora
not working if domain has some request after .com example sample.com/products how to make it work for it?Drivein
While this does work for me, it makes two redirects... and for some reason the first of those two is always a 302 redirect. This is considered an error in SEO tools like SEMRush. Does anyone know how to overcome that first 302 redirect that this code seems to trigger?Retarder
D
23

Your condition will never be true, because its like "if (a == a + b)".

I'd try the following:

RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule ^.*$ https://%1/$1 [R=301,L]

This will capture "google.com" from "www.google.com" into %1, the rest in $1 and after that combining the 2, when HTTP_HOST starts with www (with or without https).

Decomposition answered 27/9, 2009 at 17:33 Comment(4)
Unfortunately this still creates a "Connection is Untrusted" error when someone tries to access domain.comPayment
Hmm but it is redirecting properly? If it is it might be a certificate issue.Decomposition
See this for the certificate issue.Martynne
RewriteRule ^.*$ https://%1/$1 [R=301,L] wasn't working for me. if I went to mysite.com/some/path it was redirecting to just mysite.com if you change this to RewriteRule ^(.*)$ https://%1/$1 [R=301,L] (note the brackets) then it redirects as expected to mysite.com/some/pathExaminee
B
16

To enforce non-www and https in a single request, you can use the following Rule in your htaccess :

RewriteEngine on

RewriteCond %{HTTP_HOST} ^www\. [OR]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$
RewriteRule ^ https://%1%{REQUEST_URI} [NE,L,R]

This redirects http://www.example.com/ or https://www.example.com/ to ssl non-www https://example.com/ .

I am using R Temp Redirect flag for testing purpose and to avoid browser caching. If you want to make the redirect permanent , just change the R flag to R=301 .

Bellflower answered 7/3, 2017 at 16:52 Comment(8)
hmm but still when I enter site with www safari says that the page is insecure and opera does not want to redirect any option with or without www to ssl, why?Chevaldefrise
this is giving too many redirectsBalakirev
@Balakirev Try clearing your browser cache.Bellflower
of course i did thatBalakirev
@Balakirev This code works perfactly fine on apache server. Are you sure you are not using any load balancing or proxy server like Cloudflare? If you are using CloudFlare then this wont work. Please confirm.Bellflower
no, it's a regular apache server on a regular vps, no cloudflares or load balancers. actual server running apache 2.4.38 and the above code gives too many redirects. i have one server where it works and on this one it doesn't. the commands that worked on this particular server were: ` RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] RewriteRule ^(.*)$ https://%1/$1 [R=301,L] RewriteCond %{HTTP:X-Forwarded-Proto} !=https RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]`Balakirev
i think your one didn't work because {HTTPS} is not available on all servers, that one supported %{HTTP:X-Forwarded-Proto} insteadBalakirev
@Balakirev yes, thats because you are using a proxy server. {HTTP:X-Forwarded-Proto} is a variable its used to test URL scheme on proxy .Bellflower
N
10
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

This works for me perfectly!

Nonconformance answered 7/6, 2019 at 11:12 Comment(0)
O
5

This worked for me:

RewriteEngine On
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
Ocotillo answered 12/3, 2014 at 21:2 Comment(0)
I
5

Certificate must cover both www and non-www https. Some provider's certs cover both for www.xxxx.yyy, but only one for xxxx.yyy.

Turn on rewrites:

RewriteEngine On

Make all http use https:

RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://xxx.yyy/$1 [L,R=301]

Make only www https use the non-www https:

RewriteCond %{SERVER_PORT} 443
RewriteCond %{HTTP_HOST} ^www[.].+$
RewriteRule ^(.*)$ https://xxxx.yyy/$1 [L,R=301]

Cannot be processing non-www https, otherwise a loop occurs.

In [L,R=301]:

  1. L = If the rule was processed, don't process any more.
  2. R=301 = Tells browser/robot to do a permanent redirect.

More generic

A more generic approach -- not port-dependant -- is:

RewriteCond %{HTTP_HOST} ^www\.
RewriteRule ^(.*)$ https://xxxx.yyy/$1 [R=301,QSA]

to make any url with www drop it.

RewriteCond %{HTTPS} !on
RewriteCond %{HTTPS} !1
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTP:X-Forwarded-SSL} !on
RewriteRule ^(.*)$ https://xxxx.yyy/$1 [R=301,QSA]

to force any non-https url, even for those system downstream from load-balancers that drop https, use https.

Note that I have not tested the forwarded options, so would appreciate feedback on any issues with them. Those lines could be left out if your system is not behind a load-balancer.

TO HTTP_HOST or not

You can use ${HTTP_HOST} to be part of the URL in the RewriteRule, or you can use your explicit canonical domain name text (xxxx.yyy above).

Specifying the domain name explicitly ensures that no slight-of-hand character-bending means are used in the user-supplied URL to possibly trick your site into doing something it might not be prepared for, or at least ensures that the proper domain name appears in the address bar, regardless of which URL string opened the page.

It might even help convert punycode-encoded domains to show the proper unicode characters in the address bar.

Influx answered 24/1, 2015 at 15:6 Comment(0)
R
3
RewriteEngine On

RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule ^.*$ https://%1/$1 [R=301,L]

RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

This worked for me after much trial and error. Part one is from the user above and will capture www.xxx.yyy and send to https://xxx.yyy

Part 2 looks at entered URL and checks if HTTPS, if not, it sends to HTTPS

Done in this order, it follows logic and no error occurs.

HERE is my FULL version in side htaccess with WordPress:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule ^.*$ https://%1/$1 [R=301,L]

RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]


# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
Rawlins answered 15/1, 2016 at 0:57 Comment(0)
M
1

To me was better hardcoding "example.com" as string, so I need less rules, even you can use it to redirect from .org to .com or similar too:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_HOST} !^example\.com$ [NC]
  RewriteRule ^ https://example.com%{REQUEST_URI} [L,NE,R=301]
</IfModule>
Mariejeanne answered 14/6, 2018 at 18:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.