htaccess www well in home page but not in other pages - .htaccess

My .htaccess file content
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Remove index.php
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.php($|\ |\?)
RewriteRule ^ /%1 [R=301,L]
# Redirect Http To Https
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Redirect Non Www To Www
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*) https://www.%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
my example.com redirected well to www.example.com (Not problem)
my problem when I go to other pages like
example.com/page1/test redirected to www.example.com
(That my problem) I need it redirect me to www.example.com/page1/test

Your directives are in the wrong order. You need to put your canonical redirects before the front-controller - at the top of the file.
By placing the redirects at the end they are simply never going to get processed for anything other than static files/directories since everything else is routed to index.php.
Your HTTP to HTTPS redirect is also incorrect since you are unconditionally prefixing with the www subdomain.
Also, no need to repeat RewriteEngine throughout the file.
In other words, arrange your directives like this (assuming you are not intending to implement HSTS):
Options +FollowSymLinks -Indexes
RewriteEngine On
# Remove index.php
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.php($|\ |\?)
RewriteRule ^ /%1 [R=301,L]
# Redirect Non Www To Www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
# Redirect Http To Https
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
It is more efficient to use a regex like ^ to simply be successful for every URL, rather than .* that needs to traverse the entire URL-path - since you are not capturing this.
You will need to clear your browser cache before testing. Preferably test with 302 (temporary) redirects to avoid caching issues.

Related

How To Redirect www to Non-www with path url complete in apache2

All paths with www (www.example.com/posts/categories) redirect to the home page. How can i redirect from .htaccess and keep the full path?
https://www.example.com/posts/categories to https://example.com/posts/categories
current configuration:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
</IfModule>
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
You've put this rule in the wrong place. It needs to go at the start, immediately after the RewriteEngine directive. By placing it at the end, after the rewrite to index.php, any request for the www subdomain will be redirected to index.php (during the second round of processing).
As a general rule, external redirects should always go before internal rewrites.
You should also consider implementing an HTTP to HTTPS redirect.

Rewritecond by `%{HTTP_HOST}` is ignored?

I have multiple domains that point to the same folder on my server. The code in index.php page recognizes which domain is accessing it and shows different content for each domain.
Now I want that www.domain-a.com\sitemap.xml opens /sitemap-a.xml so that each domain has its own sitemap.
I use the following rule in my .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^.*domain-a\.com$
RewriteRule ^sitemap.xml$ sitemap-a.xml [NC]
However, if I access www.domain-a.com\sitemap.xml then the content from the file /sitemap.xml is shown instead of the file sitemap-a.xml.
Is the redirecting rule wrong? If so, how can I fix it?
I am using Laravel. This is the full .htaccess file:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^.*domain-a\.com$
RewriteRule ^sitemap.xml$ sitemap-a.xml [NC]
# browser request: .php to non-php
# https://stackoverflow.com/questions/13222850/redirect-php-urls-to-urls-without-extension
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^\ ]+)\.php
RewriteRule ^/?(.*)\.php$ /$1 [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Can you try this rule just above # Handle Authorization Header line:
RewriteCond %{HTTP_HOST} (?:^|\.)domain-a\.com$ [NC]
RewriteRule ^sitemap\.xml$ /sitemap-a.xml [L,NC]

How do I reduce redirect chain with .htaccess?

I've been having some problem with solving the redirect chain of my website. I wanted my website to ultimately have only one version, which is HTTPS + non-www + trailing slash
When tested, below htaccess gave me 4 response with redirect chain out of 8 total variation tested (https, www/non-www,trailing slash, 2x2x2 = 8 variations).
The http://www. variation gave me a redirect chain with 3 redirects
http://www. --> https://www. --> https://www. + trailing slash ---> https:// + trailing slash
Is there a way that I can make it no redirect chain or at least not more than 2?
Appreciate if someone could help me out! Thanks
# Force trailing slash
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1/ [L,R=301]
# HTTPS forced by SG-Optimizer
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
</IfModule>
# END HTTPS
# 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
I use this
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.mywebsite.com/$1 [L,R=301]
</IfModule>
If I understood you correctly, you want to force HTTPS//non-WWW and remove trailing slashes from files in one redirect. That's a bit demanding and require some sort of GOTO/SKIP logic in the .htaccess file. Try it like this with a fresh browser in incognito mode:
RewriteEngine on
## Check if not a directory and ends in /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
## If not a directory skip next RewriteRule
RewriteRule ^ - [S=2]
## Check if HTTPS and non-WWW
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [OR,NC]
RewriteCond %{https} off
## This RewriteRule skipped if URI was a directory
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
## This RewriteRule used if URI was a directory
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [S=1]
RewriteRule ^(.*)/$ https://example.com/$1 [R=301,L]
PS: I get the idea, but Google's Gary Illyes tweeted in 2016 "30x redirects don't lose PageRank anymore." So, even for SEO this is no longer a burning issue.

OpenCart htaccess redirect to WWW and SSL

I want to force redirect OpenCart store to its WWW version with opencart.
SEO URL Settings
RewriteEngine On
# If your opencart installation does not run on the main web folder make sure you folder it does run in ie. / becomes /shop/
RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=extension/feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=extension/feed/google_base [L]
RewriteRule ^system/download/(.*) index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
This is the htaccess part for the redirect and it works but the smart URL now are
https://www.example.com/index.php?route=the-name-of-the-product
and it should be
https://www.example.com/the-name-of-the-product
Any idea how to fix this problem with the smart urls?
Am I doing the redirect wrong or the problem is other?
Try moving the following lines at the start of .htaccess file
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Apache rewrite all URL's to https with www + a few exceptions

I've tried all the answers to similar stack questions and nothing has worked. I need to redirect all to https://www except for example.com/blogs/* and example.com/page-name.
I currently have this:
RewriteCond %{HTTPS} =off
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
RewriteCond %{http_host} ^example.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
which redirects everything except for https://example.com, it will NOT add the www.
You can see for yourself at https://moblized.com
RewriteEngine On
RewriteCond %{HTTPS} =off
RewriteRule ^(.*)$ https://www.moblized.com/$1 [R=301,L]
RewriteCond %{http_host} ^moblized.com [NC]
RewriteRule ^(.*)$ https://www.moblized.com/$1 [R=301,L]
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} blogs
RewriteRule ^(.*)$ http://moblized.com/blogs/$1 [R,L]
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
</IfModule>
# $Id: .htaccess,v 1.90.2.4 2009/12/07 12:00:40 goba Exp $
AddHandler php5-script .php
Thank you!
I hope I understood you correctly. You want:
redirect from example.com to www.example.com (except /blogs/ and /page-name)
redirect all pages to HTTPS (except /blogs/ and /page-name)
based on your current .htaccess under /page-name you mean /favicon.ico
Here are the rules for the above requirements -- put them into your .htaccess:
# activate rewrite engine
RewriteEngine On
# don't touch favicon.ico (always accept as is regardless of the domain or protocol)
RewriteRule ^favicon.ico$ - [L]
# don't touch /index.php (usually means already overwritten URL)
# otherwise we may enter into a loop
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^index\.php$ - [L]
# ensure trailing slash is present for /blogs -> /blogs/
RewriteRule ^blogs$ http://mobilized.com/blogs/ [R=301,QSA,L]
# /blogs/ should only be accessible via http://example.com/blogs/
RewriteCond %{HTTP_HOST} !^moblized\.com$ [NC]
RewriteRule ^blogs/(.*)$ http://mobilized.com/blogs/$1 [R=301,QSA,L]
RewriteCond %{HTTP_HOST} ^moblized\.com$ [NC]
RewriteCond %{HTTPS} =on
RewriteRule ^blogs/(.*)$ http://mobilized.com/blogs/$1 [R=301,QSA,L]
RewriteRule ^blogs/.* - [L]
# redirect to www.example.com if necessary
RewriteCond %{HTTP_HOST} ^moblized\.com$ [NC]
RewriteCond %{REQUEST_URI} !=/client-ipad-contest
RewriteRule ^(.*)$ https://www.moblized.com/$1 [R=301,QSA,L]
# redirect to HTTPS if not there already
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !=/client-ipad-contest
RewriteRule ^(.*)$ https://www.moblized.com/$1 [R=301,QSA,L]
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]
BTW, browser most likely will show "Untrusted Certificate" warning if your customer go to https://example.com. This is because HTTPS session has to be fully established first before the request starts processing by Apache's rewrite module.
If that is problem -- then consider buying another SSL certificate (or from another vendor) which will cover both example.com and www.example.com (GoDaddy does this for sure) or get wildcard certificate which will cover all subdomains -- *.example.com (but this most likely will be much more expensive).
UPDATE: After simulating your requirements locally (sorry, I have no SSL with working Apache, so I have replaced it (in my testing) with different kind of rule/domain name) I have revised and updated the rules.
I've tested these rules locally (all pages are very simple, just include 1 image & css and a bit of text) -- everything looking good. Let me know if something does not work.

Resources