Forum Moderators: phranque

Message Too Old, No Replies

Please help with a redirect problem.

.htaccess 301 url redirection query strings

         

lonewolfonline

7:52 am on Feb 6, 2008 (gmt 0)

10+ Year Member



Hi,

I am trying to redirect one url to another - sounds simple, but for the life of me I can't get this to work.

About a year ago I changed the url structure of my site, removed php files and tried redirects (which didn't work). I put back the php files and handled the redirect in php code.

I'm going through the site cleaning up the old files and need to get rid of these files now, so i'm revisiting the .htaccess redirect.

The urls I am trying to redirect follow this pattern:

OLD: http://example.net/doarticle.php?article=computer_howto_hpze5400

NEW: http://example.net/computers/tutorial/hp_pavilion_ze5400_dismantle/

All I need is a plain redirect. Obviously with the query string I can't use:

RedirectPermanent /doarticle.php?article=computer_howto_hpze5400 http://example.net/computers/tutorial/hp_pavilion_ze5400_dismantle/

So I have tried various other methods:

RedirectMatch ^/doarticle.php/\?article=computer_howto_hpze5400$ http://example.net/computers/tutorial/hp_pavilion_ze5400_dismantle/

and

RewriteCond %{REQUEST_URI} doarticle.php/\?article=computer_howto_hpze5400 [NC]
RewriteRule ^(.*) http://example.net/computers/tutorial/hp_pavilion_ze5400_dismantle/ [R=301,L]

The last one (RewriteCond) does seem to work, but it appends the original query string to the end of the new url and goes into a loop. Firefox reports that the page is redirecting in a way that will never complete.

I also tried this:

RewriteCond %{QUERY_STRING} ^article=computer_howto_hpze5400
RewriteRule /* http://example.net/computers/tutorial/hp_pavilion_ze5400_dismantle/ [R,L]

Which also gets stuck in a loop.

I have around 30-40 urls like this, not all doarticle.php, that need redirects. The query string is never the same as the new url. I just need a static from this, to that rule.

Many thanks in advance

regards

Tim

[edited by: jatar_k at 8:30 pm (utc) on Feb. 6, 2008]
[edit reason] please use example for domains [/edit]

jdMorgan

10:55 pm on Feb 6, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You got fairly close. You have to split the URL-path and the query string, and handle them separately, but in the same URL-specific rule:

# Setup (Options line may be required, not needed, or even not allowed by your host. Test to find out)
Options +FollowSymLinks
RewriteEngine on
#
# Individual URL+Query redirects
#
RewriteCond %{QUERY_STRING} &?article=computer_howto_hpze5400&?
RewriteRule ^doarticle\.php$ http://example.net/computers/tutorial/hp_pavilion_ze5400_dismantl[b]e/?[/b] [R=301,L]

The "&?" sequences on the query string are used to prevent matching any substring in the query string except for an exact match on that substring. They serve as "soft anchors" on the string; If a character is present in that position, it must be an ampersand. This disambiguates what might otherwise be a "too open" pattern (imagine if you also had a separate page for the hpze5400a, for example.). If you are sure that the query string will never contain any other name/value pairs in addition to "article=xyz", then you can fully-anchor the query string pattern using "^" and "$". However, you never know what a user might type-in or a robot (friendly or unfriendly) might request...

The "?" at the end of the substitution URL is a mod_rewrite token required to clear the current query string; It will not appear in the HTTP Location: response header or the in the URL subsequently requested by the client.

Now before trying this, be sure that the static URL being redirected-to is an actual, existing page. If you are using a separate RewriteRule to map these static URLs back to a script, then a different solution is required to avoid a loop between that rule and this rule. But you said all you needed was a plain redirect... I'm not sure how much to read into that statement.

Jim

lonewolfonline

7:45 am on Feb 7, 2008 (gmt 0)

10+ Year Member



Just tried a few examples and seems to work perfectly!

Many Thanks!

:)

phranque

8:23 am on Feb 7, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



welcome to WebmasterWorld [webmasterworld.com], tim!

lonewolfonline

7:18 pm on Feb 14, 2008 (gmt 0)

10+ Year Member



just found two more rules that are defeating me...

trying to redirect "http://example.net/astro_nightsky.php?const=lynx" to "http://example.net/astronomy/constellations/lynx/" using the rule:

RewriteRule /astro_nightsky.php?const=(.*) http://example.net/astronomy/constellations/$1/? [R=301,L]

And I can't for the life of me find why it isn't working...?

I have an existing rule

RewriteRule /showgallery.php?n=(.*) http://example.net/pictures/$1/? [R=301,L]

Which works fine.

Also, G seems hell-bent on trying to index (for example) /showgallery.php?n=1234 as well as /showgallery.php/?n=1234. Why the additional forward slash in front the question mark, and how do I stop it. These urls are not in my sitemap, nor do they appear on the site. Is there a rule that will match /? and return a 404 or 410? Better way of handling this without doubling up on my already extensive list of rewrites?

Thanks again.

Tim

g1smd

10:53 pm on Feb 14, 2008 (gmt 0)

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



If the query string always contains n= then you test for that, and capture the query into %1, and can capture the path to index.php (without the trailing /) into $1 and then redirect to the new URL without the / included.

Something like:
RewriteCond %{QUERY_STRING} n=(.*)
RewriteRule ^(.*/index\.php)/$ http://www.example.net/$1\?n=%1 [L,R=301]

Or maybe:
RewriteCond %{QUERY_STRING} n=
RewriteRule ^(.*/index\.php)/$ http://www.example.net/$1 [L,R=301]
...assuming that the query string will be automatically added back on the end of the target URL.

jdMorgan

3:24 am on Feb 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Tim,

Your code demonstrates that you've forgotten the main lesson of my post above -- query strings cannot be handled by RewriteRule alone.

Jim