forcing site to https and working both for www or non www

Black Sulfur
Black Sulfur used Ask the Experts™
on
I have updated a website that has been around for a while. I checked to see what the url looks like if I search for it on Google and it is www as opposed to not having www. I wanted to keep that but also force a redirect to https as the site was http. I have added a SSL certificate so it should be https.

I have done this in the root .htaccess file, bearing in mind this is a php MVC structured project (just mentioning in case that matters at all).

<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{HTTPS} off 
 RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
 RewriteRule ^$ public/ [L]
 RewriteRule (.*) public/$1 [L]
</IfModule>

Open in new window


So, this works fine if I click on the link from the google search results and if I type www.mysite.com directly into the browser url.

But, if I just type in mysite.com then it loads the site but doesn't force the www and some things on the site do not work anymore.

Console gives me a bunch of these errors:

has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

So, firstly, what is the best way to fix this and secondly, am I not meant to choose a preferred version and somehow state that via a canonical tag or something along those lines. I am concerned google will think there is duplicate content if both www and non www sites work or is that not an issue?

Any advice would be appreciated.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Hi here the code I'm using and it's work well in any case

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

Open in new window



About the access-control-allow-origin
https://crunchify.com/how-to-fix-access-control-allow-origin-issue-for-your-https-enabled-wordpress-site-and-maxcdn/


You have to make sure that all internal url is using https (all external link too if possible)

Author

Commented:
Thanks, lenamtl. That is pretty much the code I am already using. Even if I fix the allow origin issue, I am still concerned about being penalised for potential duplicate content if the site works on both www and non www. That's also part of my question.
Martyn SpencerSoftware Developer / Linux System Administrator

Commented:
My understanding is that if you redirect with a 301, you will not be penalised for duplicate content.
11/26 Forrester Webinar: Savings for Enterprise

How can your organization benefit from savings just by replacing your legacy backup solutions with Acronis' #CyberProtection? Join Forrester's Joe Branca and Ryan Davis from Acronis live as they explain how you can too.

Martyn SpencerSoftware Developer / Linux System Administrator

Commented:
I read somewhere (sorry, I cannot remember where) that using the rewrite engine is not the most optimal way of handing a redirect from http to https and that modifying your vhost configuration is more efficient (assuming that you have access). With that in mind, doing something like this is recommended:
NameVirtualHost *:80
<VirtualHost *:80>
   ServerName mysite.example.com
   DocumentRoot /usr/local/apache2/htdocs 
   Redirect permanent / https://mysite.example.com/
</VirtualHost>…

Open in new window

(The above was taken from https://stackoverflow.com/questions/16200501/http-to-https-apache-redirection#16201658)

This kind of permanent redirect will still emit a 301 permanently moved http response. The most relevant line is:
Redirect permanent / https://mysite.example.com/

Open in new window

Fractional CTO
Distinguished Expert 2018
Commented:
About Google index listing format...

You said, "I checked to see what the url looks like if I search for it on Google".

Keep in mind, whether you see index listings of www or bare domain depends on this.

1) What you've set as index listing in Google Search Console.

2) If undefined, Google will choose what shows up in the index based on factors including 301s + 302s (as Martyn mentioned).

Also, backlink weight seems to take precedence... In other words...

If you haven't specified index listing type in Google Search Console, Google will evaluate the entire index ecosystem + try determining if more backlinks reference www or bare domain.

It's unclear in this situation exactly what directory listing will show up.

Tip: If you require having complete control over this, first setup Google Search Console to show directory listing of your choice.

That said...

About forcing HTTPS for all links...

Your .htaccess rules are to simple + can look like potentially you may have a duplicate content penalty for every page, which will promote this to a site wide duplicate content penalty, in which case your index rank will be decreased or potentially all links will be expunged from the index.

Here's the Virtual Host stanzas I use for site to protect against this problem.

Note: The following produces a terminal link of https://baredomain.com (no www), so if you're trying to use www as your terminal link, you'll have to rewrite the following to switch sense from bare domain to www...

<VirtualHost *:80>
   ServerName  www.WEBSITE
   ServerAdmin support@WEBSITE
   RewriteEngine on
   RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
   RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [NC,L,R=301]
   Include logging.conf
</VirtualHost>

<VirtualHost *:80>
   ServerName  WEBSITE
   ServerAdmin support@WEBSITE
   RewriteEngine on
   RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [NC,L,R=301]
   Include logging.conf
</VirtualHost>

<IfModule mod_ssl.c>

   <VirtualHost *:443>

      ServerName  www.WEBSITE
      ServerAdmin support@WEBSITE

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

      Include logging.conf

      SSLEngine on
      SSLUseStapling on

      SSLCertificateFile    /etc/letsencrypt/live/WEBSITE/fullchain.pem
      SSLCertificateKeyFile /etc/letsencrypt/live/WEBSITE/privkey.pem

      # Enable HTTP Strict Transport Security with a 2 year duration
      Header always set Strict-Transport-Security "max-age=63072000; preload"

   </VirtualHost>

   <VirtualHost *:443>

      ServerName  WEBSITE
      ServerAdmin support@WEBSITE

      DocumentRoot /sites/OWNER/WEBSITE/TYPE

      <Directory /sites/OWNER/WEBSITE/TYPE>
          Options +Indexes +FollowSymLinks
          AllowOverride All 
          Require all granted
      </Directory>

      Include logging.conf

      SSLEngine on
      SSLUseStapling on

      SSLCertificateFile    /etc/letsencrypt/live/WEBSITE/fullchain.pem
      SSLCertificateKeyFile /etc/letsencrypt/live/WEBSITE/privkey.pem

      # Enable HTTP Strict Transport Security with a 2 year duration
      Header always set Strict-Transport-Security "max-age=63072000; preload"

   </VirtualHost>

</IfModule>

Open in new window


When first setting up to force all links to HTTPS, I'd suggest you comment out HSTS lines + change all 301s to 302s.

Debug with these settings, then after everything's working, flip back.

Tip: Best way to quickly debug forcing HTTPS, without wrestling with browser caching nonsense is this command...

curl -I -L URL | egrep -i -e ^http -e ^location

Open in new window


This will recursively walk all your redirects + produce the terminal link.

For example...

# curl -s -I -L http://DavidFavor.com | egrep -i -e ^http -e ^location
HTTP/1.1 301 Moved Permanently
Location: https://DavidFavor.com/
HTTP/2 200

Open in new window


Using curl gives you instant, 100% correct info, with no browser cache interference.

Author

Commented:
Thanks guys, the vhost examples are pretty foreign to me. How do I even start?

I am on a shared hosting package (php)

I updated my .htaccess file which seems to force https://www. but I would like to do the vhost method if I am able to.

<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{HTTP_HOST} (?!^www\.)^(.+)$ [OR]
 RewriteCond %{HTTPS} off
 RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L]
 RewriteRule ^$ public/ [L]
 RewriteRule (.*) public/$1 [L]
</IfModule>

Open in new window

Martyn SpencerSoftware Developer / Linux System Administrator

Commented:
If you are on a shared hosting package, I doubt you would have access to the server configuration so rewrite rules will be the way to go and David's information is really very useful. If you wanted to globally redirect all non https traffic, you could possibly ask your hosting provider to make a change for you that is compliant with Google's indexing.

Author

Commented:
Yes, I wanted to try David's way because after having a quick Google now, most resources say that using the .htaccess file to do what I am trying to should be a last resort. But I guess if I am on shared hosting I don't have much of a choice.
Martyn SpencerSoftware Developer / Linux System Administrator

Commented:
Yes, you are a little limited when on shared hosting unless they are prepared to make changes to your configuration, which generally isn't the case.
David FavorFractional CTO
Distinguished Expert 2018

Commented:
You can usually get away with doing this in a .htaccess file + this can be tricky.

For example, WordPress (and other software) rewrites .htaccess constantly + sometimes .htacess files can end up scrambled.

My personal preference is to place core Apache directives (required for minimal site function to work) in the Apache config, so these directives are protected against any file changes.

If you do use .htaccess for this, be sure to keep notes somewhere of all your rules, so you can recreate the .htaccess file if required.

Author

Commented:
Thanks guys, since EE took away points allocation using actual numbers, all I have is these sliders and I don't actually know how they allocate points. So, apologies if the points come out weird. I have asked them to change it back but no go....

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial