Forum Moderators: phranque

Message Too Old, No Replies

Redirect dynamic urls

         

mike152

12:36 pm on Nov 5, 2011 (gmt 0)

10+ Year Member



Hello everyone,
I got one issue, been working on it for hours and didnt find the solution so I am pretty tired now.
Ive tried to rewrite and redirect dynamic urls on my site with 2 variables in htaccess. My link was:
website.com/index.php?id=123&n=name

I used this code:
RewriteRule ^([^/]+)_([^/]+)$ /index.php?id=$1&n=$2 [NC]

And I get this link:
website.com/123_name

Id like to get this link:
website.com/name
but its hard or me, so I kept it that way, it could work.
The problem is, I want old link to redirect to new, which is such a problem I cannot solve.

I tried this:
RewriteCond %{QUERY_STRING} ^id=(.+)&n=(.+)$
RewriteRule . http://example.com/%1_%2? [R=301,L]
But there is an error.
Could anyone help?
Thanks

[edited by: jatar_k at 1:09 pm (utc) on Nov 5, 2011]
[edit reason] changed url to stop autolinking for readable rule [/edit]

g1smd

8:25 pm on Nov 5, 2011 (gmt 0)

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



You need the RewriteCond for the redirecting rule to test THE_REQUEST, not QUERY_STRING, so that you do not get an infinite redirect -> rewrite -> redirect -> rewrite loop.

^([^/]+)_([^/]+)$
is "not a slash" (one or more times), followed by underscore, followed by "not a slash" (one or more times).

The first "not a slash" (one or more times) consumes the whole input. It does this as there is nothing to make it stop consuming when it encounters an underscore because it isn't looking for underscore, it is looking for "not a slash". Use [^/_] instead. You might even need [^/_.] to be sure you do not capture requests with an extension.

Likewise the first (.+) consumes the first parameter value and all of the following parameters. Use ([^&]+) instead.

The rule will also fail to redirect if there are other parameters before or after these, or others between these, or if these two paramters are in a different order. Those would be more sources of duplicate content, so you need to redirect all combinations.

lucy24

11:28 pm on Nov 5, 2011 (gmt 0)

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



Likewise the first (.+) consumes the first parameter value and all of the following parameters. Use ([^&]+) instead.

There are a surprising lot of queries running around with null parameters, so it is probably safest to deal with them somewhere along the line. If you're doing the redirect-plus-rewrite two-step (this usually seems to be the case with parameters) you may want to detour to something that inserts a default value in any essential parameters.

I'd be tempted to have two separate Conditions, each of them looking at one {QUERY_STRING}:

[&?]id=([^&]*)
and, separately,
[&?]n=([^&]*)

Put them in the order you want to use them in, and then the captures will always be %1 and %2.

mike152

3:32 pm on Nov 6, 2011 (gmt 0)

10+ Year Member



OK thank you guys for answers, the rewrite is ok, but redirect still doesnt work.
I tried these:
RewriteEngine on
RewriteRule ^([^/_.]+)_([^/_.]+)$ /index.php?id=$1&n=$2 [NC]
RewriteCond %{THE_REQUEST} ^id=([^&]+)&n=([^&]+)$
RewriteRule . http://example.com/%1_%2 [R=301,L]

And:
RewriteEngine on
RewriteRule ^([^/_.]+)_([^/_.]+)$ /index.php?id=$1&n=$2 [NC]
RewriteCond %{QUERY_STRING} ^[&?]id=([^&]*)
RewriteCond %{QUERY_STRING} ^[&?]n=([^&]*)
RewriteRule . http://example.com/%1_%2 [R=301,L]

Am I missing something?
Any suggestions?
Thank you.

g1smd

6:30 pm on Nov 6, 2011 (gmt 0)

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



You're missing the [L] flag on the end of every Rule.

For readability, leave a blank line after every RewriteRule.

List the redirecting code before the rewriting code.

Your RegEx pattern for the redirect is incorrect. It needs to match the actual GET request sent by the browser. This is in the form "GET /<somestuff> HTTP/1.1"

mike152

12:13 am on Nov 7, 2011 (gmt 0)

10+ Year Member



great, thanks a lot, now here is the code which works finally:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{THE_REQUEST} id=([^&]+)&n=([^&]+)HTTP/1.0$
RewriteRule . http://example.com/%1_%2? [R,L]
RewriteRule ^([^/_.]+)_([^/_.]+)$ /index.php?id=$1&n=$2 [L]

g1smd

12:21 am on Nov 7, 2011 (gmt 0)

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



Your value for n= will at the very least contain a trailing space.

Leave off the 1.0$ unless you really do want to detect only HTTP/1.0 requests.

Leave a blank line after every RewriteRule.

You have a 302 redirect. Are you sure that's what you want?

lucy24

1:11 am on Nov 7, 2011 (gmt 0)

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



Overlapping

Do all your visitors come from specific locations?

I'd always associated HTTP/1.0 with elderly robots or outdated browsers, but it turns out it's a function of the connection, not the UA.

mike152

12:41 pm on Nov 7, 2011 (gmt 0)

10+ Year Member



The 302 redirect was only for testing now it is 301.
And there is a space youre right. I thought it was ok, but this is a problem, so my code now looks like this:

Options +FollowSymLinks
RewriteEngine on
RewriteCond %{THE_REQUEST} id=([^&]+)&n=([^&]+)HTTP
RewriteRule . http://example.com/%1_%2? [R=301,L]

RewriteRule ^([^/_.]+)_([^/_.]+)$ /index.php?id=$1&n=$2? [L]

but the space is still there. I am out of ideas.

g1smd

12:49 pm on Nov 7, 2011 (gmt 0)

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



(\?|&)id=([^&]+)&n=([^&\ ]+)(&[^\ ]+)?\ HTTP/

mike152

5:09 pm on Nov 7, 2011 (gmt 0)

10+ Year Member



works fine, thank you for great help