'url not redirecting correctly to canonical

My website uses .htaccess redirect as below:

RewriteEngine On    
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

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

The issue is that

Warning, no 301 redirects are in place to redirect traffic to your preferred domain. Pages that load successfully both with and without www. are treated as duplicate content! Not all versions of your page point to the same URL.

URL Resolved URL:

  1. http://example.com/inner-page redirects to https://example.com/inner-page
  2. http://www.example.com/inner-page redirects to https://example.com/index.php/inner-page
  3. https://example.com/inner-page redirects to https://example.com/inner-page
  4. https://www.example.com/inner-page redirects to
    https://example.com/index.php/inner-page

Why the same URL is behaving differently with browser. What should I change in the .htaccess file so that it can redirect to the proper URL? I'm wondering how this strange behaviour can happen?

What is the solution so that they all redirect to only

https://example.com/inner-page

any help will be highly appreciated.



Solution 1:[1]

tl;dr Your rules are in the wrong order. You are redirecting to HTTP, not HTTPS. You are not specifically redirecting HTTP to HTTPS.


  1. http://example.com/inner-page redirects to https://example.com/inner-page

This redirect is not performed by the .htaccess directives you've posted. This is probably triggered by your PHP/application.

Your rule in .htaccess only redirects www.example.com, not example.com.

  1. http://www.example.com/inner-page redirects to https://example.com/index.php/inner-page

Because your rules are in the wrong order. The first rule rewrites the request to /index.php/inner-page first and it's this URL that is then being redirected. But this is actually 2 redirects, since the directives you've posted redirect to HTTP, not HTTPS.

Your 2nd rule will trigger a redirect to http://example.com/index.php/inner-page (note HTTP) and your PHP/application is probably redirecting this to HTTPS (see above).

  1. https://example.com/inner-page redirects to https://example.com/inner-page

That's not a redirect. Nothing is happening in this scenario. (Which is correct.)

  1. https://www.example.com/inner-page redirects to https://example.com/index.php/inner-page

Same as #2 above. (Except you are redirecting the request back to HTTP first and you are relying on PHP/application redirecting back to HTTPS - see above.)

Your current rules do not specifically redirect HTTP to HTTPS, they only redirect www to non-www. And this should redirect to HTTPS, not HTTP.

Try the following instead:

RewriteEngine On

# Redirect www to non-www (+ HTTPS)
RewriteCond %{HTTP_HOST} ^www\.(example\.com) [NC]
RewriteRule (.*) https://%1/$1 [R=301,L]

# HTTP to HTTPS
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]

# Front-controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php/$1 [L]

The HTTP to HTTPS redirect assume the SSL cert is managed by your application server, ie. you are not using a CDN, load balancer, front-end caching proxy etc. (Otherwise this might trigger a redirect loop.)

Test first with 302 (temporary) redirects to avoid potential caching issues.

You will need to clear your browser cache before testing.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1