.htaccess redirect www to non-www with SSL/HTTPS

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?

159992 次浏览

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).

This worked for me:

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

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.

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]
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

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 .

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]

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>
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!