RewriteRule violates while switching from https to http

老子叫甜甜 提交于 2019-12-20 05:49:12

问题


I write a lot of RewriteRule in my .htaccess file , but problem occurs when I switch from https to http pages; it does not follow these rules

NOTE : everything working fine on localhost , issues are on server <---- UPDATE

Here is my website , currently all links display as per RewriteRule*

for e.g. about us page link display as

http://www.mywebsite.com/about

BUT

if I am at login page ( which is on https ) and click on about us page then it turns into below.

http://www.mywebsite.com/about?slug=about_us

or if I click on any category on left panel then it comes as

http://www.mywebsite.com/auction/category/1?cid=1

Note : even mouse hovering on pages display rewrite link

below is .htaccess file with needed information.

IndexIgnore *

RewriteEngine on
Options +FollowSymLinks 
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^auction/category/([0-9]+)/?$ bids.php?cid=$1 [NC]

RewriteRule ^login/?$ login.php [NC]
RewriteRule ^register/?$ register.php [NC]
RewriteRule ^logout/?$ logout.php [NC]

# static pages
RewriteRule ^about/?$ page.php?slug=about_us [NC]

# Rewrite to https
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} /login [OR]
RewriteCond %{REQUEST_URI} /do_login.php     
RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L,QSA]

# don't do anything for images/css/js (leave protocol as is)
RewriteRule \.(gif|jpe?g|png|ico|css|js)$ - [NC,L]

# traffic to http:// except some pages
RewriteCond %{SERVER_PORT} ^443$ [OR]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !(/login|/do_login.php)
RewriteRule ^(.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L,QSA]

Note : Here is complete .htaccess file

Please tell me where I am wrong/missing ?

I Also have few more confusion

  • If i change the case of rewrite URL ( Login or lOgin or logiN ) then it gives error?
  • Is it good practice to write [NC,L] with all RewriteRule?
  • Exactly when I should write [QSA] ?

UPDATE

After suggestions from all answers, changing in RewriteRule almost fixed all issue but now there is one last issue.

  • /login URL always changed into /login.php.

below is my updated .htaccess

IndexIgnore *
Options -MultiViews
Options +FollowSymLinks

#mod_rewrite
RewriteEngine on
RewriteBase /

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

# minimize the css on all http:// pages
<IfModule mod_rewrite.c>
    RewriteCond %{HTTPS} off
   RewriteRule ^(.*).css$ /csszip.php?file=$1.css [L]
</IfModule>

#switch over http to https

# Rewrite to https
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} off

RewriteCond %{REQUEST_URI} (/login|/do_login)\.php [NC]
RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# don't do anything for images/css/js (leave protocol as is)
RewriteRule \.(gif|jpe?g|png|ico|css|js)$ - [NC,L]

# traffic to http:// except some pages
RewriteCond %{SERVER_PORT} ^443$ [OR]
RewriteCond %{HTTPS} on

RewriteCond %{REQUEST_URI} !(/login|/do_login)\.php [NC]

RewriteRule ^(.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^login/?$ login.php [NC]
RewriteRule ^register/?$ register.php [NC]
# ...many other rules...with [NC] falg

RewriteRule ^auction/category/([^/.]+)/?$ bids.php?cid=$1 [NC]
RewriteRule ^about/?$ page.php?slug=about_us [NC]
# ...many more rules.... with [NC] flag

回答1:


HTTPS suggestion

For your HTTPS issue I would match on port or HTTPS as there are known apache problems relating to the HTTPS tag.

To cover this match on both (as shown in your edited answer)

RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} != on

##REWRITE RULE

RewriteCond %{SERVER_PORT} ^443$ [OR]
RewriteCond %{HTTPS} = on

##REWRITE RULE

A valid point is also that %{REQUEST_URI} isn't affected by any substitutions.

The way you are using it at the moment, if any rule matches you will send them to the original url (before any substitution started).

If you want to take the url after and substition and matching use $1


Answers to your further questions:

If I change the case of rewrite URL then it gives error?

This is because your [NC] isn't on the rewrite cond for the HTTPS section of your .htaccess

You match RewriteCond %{REQUEST_URI} /login [OR] this is only looking for lower case login, if you want to accept uppercase login append NC.


Is it good practice to write [NC,L] with all RewriteRule?

No, it depends what you want to do [NC] says don't match case on this rule, if you don't want to match case on that rule (or condition) then add it.

Not matching the case with [NC] means site.com/login.php = sYte.cOm/LoGin.PHP

[L] means if this is true, stop processing everything


Exactly when I should write [QSA] ?

QSA applies when you have a ? in your substitution and you want to append toe old string to the new URL

Consider the following rule:

RewriteRule /pages/(.+) /page.php?page=$1 [QSA]

With the [QSA] flag, a request for /pages/123?one=two will be mapped to /page.php?page=123&one=two. Without the [QSA] flag, that same request will be mapped to /page.php?page=123 - that is, the existing query string will be discarded.

Do use QSA if you want to keep any additional get arguments.


Another further question

/login URL always changed into /login.php

The only way for this to happen is if you have a redirect [R=301] somewhere in your code, the only place I can see that is this section:

# Rewrite to https
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} != on
RewriteCond %{REQUEST_URI} (/login|/do_login)\.php [NC]
RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Where this will only match the following URL's

.php, /login.php, /do_login.php

I believe the culprit is as I outlined in the first response with %{REQUEST_URI}

Your code essentially says, if these conditions are met, send them to https://theurltheywentto, which is not what you want to do, you want to send them to /login.

Have you tried using (as mentioned in my https section)

RewriteRule ^(.*) https://%{HTTP_HOST}/login [R=301,L]

Or perhaps (if you have /do_login) and other options

RewriteRule ^(.*).php https://%{HTTP_HOST}/$1 [R=301,L]

Where test.com/do_login.php will become https://test.com/do_login

How about you try:

# Rewrite to https
RewriteCond %{REQUEST_URI} (/login|/do_login)\.php [NC]
RewriteCond %{HTTPS} != on
RewriteRule ^(.*)\.php https://%{HTTP_HOST}/$1 [R=301,L]



回答2:


I think this might be of your help

.htaccess redirect https to http not working

and for last question this might be of your help

http://httpd.apache.org/docs/current/rewrite/flags.html and

http://www.addedbytes.com/download/mod_rewrite-cheat-sheet-v2/png/

EDIT: You can try using

RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{SERVER_PORT} !^443$

instead of

RewriteCond %{HTTPS} on [NC]
RewriteCond %{HTTPS} off [NC] 

For detail

Please see this link, someone had similar problem. Please see second reply of the post

http://www.webmasterworld.com/apache/3228459.htm




回答3:


you can solve this by creating the domain alias

You can't do it within .htaccess, but within a http.conf <VirtualHost> section you can use the ServerName and ServerAlias directives to accomplish this.




回答4:


Your confusion over /about is due to redirecting to %{REQUEST_URI}, which isn't changed as you make substitutions. Capture the URI and use $1 if you don't really want the URI as it started uring this round of rewrite processing.



来源:https://stackoverflow.com/questions/12400792/rewriterule-violates-while-switching-from-https-to-http

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!