Forum Moderators: phranque

Message Too Old, No Replies

Redirecting query strings with .htaccess

htacces rewrite

         

kraaness

9:29 pm on Jun 1, 2009 (gmt 0)

10+ Year Member



Greetings,

I'm running a trailing slash webpage, and have come across a few problems with my rewriting.

First of all I use a standard code to redirect all traffic from *.domain.com to www.domain.com:
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]

I then have a set of internal rewrites:
RewriteRule ^/news/$ root/index.php [L]
RewriteRule ^/ajax/$ root/ajax.php [L]
RewriteRule ^/member/$ root/member.php [L]
RewriteRule ^/member/(.+)/$ root/member.php?user=$1 [L]
RewriteRule ^/member/(.+)/(.*)/$ root/member/$1/ [L,R=301]

etc... :)

I then redirect all user requests for .php extensions:
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /[^?]*\.php[^&\ ]*\ HTTP/
RewriteRule (.*) root/ [R=301,L]

I then add a trailing slash on every url that doesn't have one:
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}¦/)$
RewriteRule (.*)$ root/$1/ [R=301,L]

--
Now to my problem, everything is working fine except 2 things.

root/member.php?user=john redirects to root/?user=john
[2] root/?user=john does no redirect

Any way to have these two redirected to their respective location? (root/)

Thanks in advance!
kraaness

[1][edited by: jdMorgan at 10:34 pm (utc) on June 1, 2009]
[edit reason] example.com [/edit]

jdMorgan

9:59 pm on Jun 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



First, if this code is in .htaccess, then none of your internal redirects should be working, since RewriteRule in .htaccess will never 'see' a leading slash on the requested URL-paths (so your patterns won't match).

Second, although you've listed two 'problems,' you have not described what is wrong. We don't know what the expected/desired dispostion of these two URLs should be.

Your ".php extensions redirect rule," although flawed, should redirect both of these URLs to root, although you did not clear the query string, so it will still be there.

Every rule in this file has a flaw, but let's address your 'main' problem first. What happens if you delete or comment-put everything else, and just test your two "problem URLs" against this modified rule:


# redirect all user requests for .php extensions:
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /[^.\ ]+\.php[?]?[^&\ ]*\ HTTP/
RewriteRule ^(.+\.php)$ http://www.example.com/root/? [R=301,L]

A request for root/member.php?user=john should be redirected to root/ and a request for root/user=john should not be redirected, since it does not end in ".php".

Jim

[edited by: jdMorgan at 9:59 pm (utc) on June 1, 2009]

kraaness

10:07 pm on Jun 1, 2009 (gmt 0)

10+ Year Member



Hi Jim, and thanks for your assistance.

When I made the example for rewriting I did a mistake, cause they are in a dir called hp/ so the rule I use is:
RewriteRule ^hp/member/$ http://www.example.com/hp/member.php [L]

I commented all rules except the one supplied by you, and it redirects urls with hp/*.php and hp/.php?*, but not urls with hp/?*

Any way to make the .php string optional, like you have with the question mark?

Kim

[edited by: jdMorgan at 10:35 pm (utc) on June 1, 2009]
[edit reason] example.com [/edit]

jdMorgan

10:40 pm on Jun 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You don't seem to be very sure of your requirements. If you want to redirect direct client requests for URLs with blank or single name/value-pair query strings, then

# redirect all user requests with blank or single name/value pair queries
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /[^?]*\?[^&\ ]*\ HTTP/
RewriteRule ^(.*)$ http://www.example.com/root/? [R=301,L]

Please post only accurate example URLs and code, changing only the domain to example.com. Otherwise we may waste a lot of time and effort debugging problems that are not really there...

Jim

[edited by: jdMorgan at 10:41 pm (utc) on June 1, 2009]

g1smd

11:06 pm on Jun 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



There's quite a lot of stuff in that code that can be improved. I'll just mention one thing.

*** I use a standard code to redirect all traffic from *.domain.com to www.domain.com ***

Look carefully again at your code. It doesn't match that description. It matches only example.com. It does not match *.example.com at all. It has other flaws if the request arrives with appended port numbers, etc, and I'm sure Jim will fix that too in the final solution.

I just wanted to mention this one item to reinforce that clear and accurate description of the problem, and the example URLs, is vital. Too many times I have seen perfect code which fixes a different problem than the one that was actually required to be fixed.

kraaness

11:11 pm on Jun 1, 2009 (gmt 0)

10+ Year Member



That's it ! thanks alot

My apologies for the complications, not my intention to waste anyones time. I will surely have a bigger readup on regex in the future as this is by far more complex than I imagined :)

Edit: Oh I wasn't aware of that g1smd, but I only need example.com redirected to www.example.com, sorry for yet another typo. If there are flaws in the additional codes I would like to address them however, thanks.

g1smd

11:53 pm on Jun 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You will actually need
example.com
and
example.com.
and
example.com:80
and
www.example.com.
and
www.example.com:80
and so on, all to be redirected - but that is very easy to do.

We have covered that here a few times before. The reason is to prevent Duplicate Content indexing.

jdMorgan

2:46 am on Jun 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Re-ordering and clean-ups:

# Redirect all user requests to remove blank or single name/value pair queries
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /[^?]*\?[^&\ ]*\ HTTP/
RewriteRule ^(.*)$ http://www.example.com/root/? [R=301,L]
#
# Redirect to add missing trailing slash if no file extension is present on the URL
RewriteCond %{REQUEST_URI} !(\.[a-z0-9]{1,5}¦/)$ [NC]
RewriteRule ^(.*)$ http://www.example.com/root/$1/ [R=301,L]
#
# Redirect non-canonical hostname requests to the canonical hostname
RewriteCond %{HTTP_HOST} ^example\.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com(\.¦\.?:([0-9]+) [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
#
# Alternate (simpler and more robust) rule to replace the one above
# Redirect to canonical hostname
RewriteCond %{HTTP_HOST} !^www\.example\.com$
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
#
# internal rewrites:
RewriteRule ^hp/news/$ root/index.php [L]
RewriteRule ^hp/ajax/$ root/ajax.php [L]
RewriteRule ^hp/member/$ root/member.php [L]
RewriteRule ^hp/member/(.+)/$ root/member.php?user=$1 [L]
#
# The following rule was a redirect, not a rewrite. If a redirect is what is desired, then this code
# should precede all internal rewrites. Place it before the domain canonicalization redirect above.
RewriteRule ^hp/member/(.+)/(.*)/$ http://www.example.com/root/member/$1/ [R=301,L]
# ... etc

Important: Replace the broken pipe "¦" characters above with solid pipe characters before use; Posting on this forum modifies the pipe characters.

Jim

g1smd

7:51 am on Jun 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'd add a rule in there to fix up what happens if a URL request contains "index.php" in it (so that it redirects to canonical format - with www and ending with slash, not with filename).

kraaness

10:48 am on Jun 2, 2009 (gmt 0)

10+ Year Member



This fixes all my problems, but doesn't fix what g1smd was kind enough to list.

http://example.com:80 gives a 400 error
http://example.com. gives a 400 error
http://www.example.com. redirects to http://www.example.com/www./

and I used your 2nd rule for canonicalization and commented out the first

kraaness

2:15 pm on Jun 2, 2009 (gmt 0)

10+ Year Member



update: http://www.example.com. now redirects properly

problem still exists in
http://example.com:80
http://example.com.

both returns 400 error