-->

https in htaccess and order of rules (using Expres

2019-07-16 07:53发布

问题:

I'm building a site in expression engine that part of needs to be https. The site is also using a new domain name (new one www.example-new.com the old one www.example.old.com).

I want to do the following things:

  1. remove the index.php
  2. force www
  3. force https for any url starting www.example.old.com/extranet
  4. redirect https URLs that are not www.example.old.com/extranet (e.g. www.example.old.com/news to http

I have the following code so far that works for the first two requirements:

    <IfModule mod_rewrite.c>
RewriteEngine On
# Force www
RewriteCond %{HTTP_HOST} ^example-new.com$ [NC]
RewriteRule ^(.*)$ http://www.example-new.com/$1 [R=301,L] 

# Removes index.php
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

</IfModule>
AddType x-httpd-php53 .php

I seem to be going round in circles, so I've two questions that will help me write the other rewrites (although feel free to share suggestions...):

1) Should the code for requirements 3 and 4 be positioned before "removes index.php" code?

2) Does the position have any bearing on the redirects that will be coming from the old site e.g. www.example-old.com/some-link-here.asp will be redirected to www.example-new.com/some-new-link-here

Thanks,

Gregor

回答1:

1) Remove 'index.php' from ExpressionEngine URLs

RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

2) Add 'www' to all URIs

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

3) Force https:// for any URI starting with /extranet

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

4) Redirect https:// URIs that are not /extranet

RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/extranet(.*)$ [NC]
RewriteRule . http://%{HTTP_HOST}%{REQUEST_URI}$1 [R=301,L]

Putting it all together, here's your complete set of RewriteRules:

<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine on

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

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

    RewriteCond %{HTTPS} on
    RewriteCond %{REQUEST_URI} !^/extranet(.*)$ [NC]
    RewriteRule . http://%{HTTP_HOST}%{REQUEST_URI}$1 [R=301,L]

    RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>


回答2:

1) Should the code for requirements 3 and 4 be positioned before "removes index.php" code?

The rules are processed in the order that you write them. I expect that you want the site to redirect first then do the remove index, so yes, it should go before

2) Does the position have any bearing on the redirects that will be coming from the old site e.g. www.example-old.com/some-link-here.asp will be redirected to www.example-new.com/some-new-link-here

If you are using the same directory for both sites, then you would need to prefix all rules for one site with a RewriteCond that limits the domain. Otherwise, order of the rules (old vs new site) is important.

Your redirects from the old site should also incorporate rules in the new e.g. ensure that you are going to http/s as necessary to avoid extra redirects.

Below is the code to force http/s

#if not secure
RewriteCond %{HTTPS} off 
#and starts with /extranet
RewriteCond %{REQUEST_URI} ^/extranet [NC]
#redirect to secure
RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

#if  secure
RewriteCond %{HTTPS} on
#and does not start with /extranet
RewriteCond %{REQUEST_URI} !^/extranet [NC]
#redirect to http
RewriteRule . http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]


回答3:

# force www on hostname, but keep same protocol (http/https)
RewriteCond %{HTTP_HOST} !^www\.(.+)
RewriteCond %{HTTPS}s ^(on(s)|offs)
RewriteRule ^ http%2://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]


回答4:

If it helps... I just did this yesterday for an ecommerce site... Here's my .htaccess file

# Remove WWW from URL
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]

# Add a trailing slash to paths without an extension
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)$ $1/ [L,R=301]

#remove index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1

#Force HTTPS on checkout/account pages
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} (checkout|account)
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

#remove HTTPS on all other pages
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(img|_|images|checkout|account)
RewriteRule ^(.*)$ http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]