Forum Moderators: phranque

Message Too Old, No Replies

htaccess redirect dynamic URL endless loop issue

dynamic URL redirect htaccess endless loop

         

NathanD

11:33 pm on Mar 12, 2009 (gmt 0)

10+ Year Member



Hi everyone - after quite a bit of researching over the years on everything from CSS to Apache, I've usually found threads at this fine forum that have helped me greatly, but for this issue I've had no such luck (sorry if it is a reposted Q, but I did try to find the answer first).

My issue is concerning redirecting with .htaccess. Let me first setup my situation.

My site used to be in the /view.php?linkid=1 form. Recently, during a complete site redesign, I've discovered the wonders of mod_rewrite. The URL for this page on my site will soon be /view/1/post-title/. It looks better, and I believe it may even help regarding SEO.

Anyway, to do this, I have the following rule in my .htaccess:

RewriteRule ^view/([0-9]*)/[a-zA-Z0-9-]*/?$ view.php?linkid=$1 [NC]

This works great. However, I have a slight problem - my old style URLs still work, and google has indexed my old /view.php?linkid=x format URLs. So when the new site is rolled out, google will see new URLs with the same content, which i've read isn't ideal.

So I need to do a 301 redirect. To achieve this, I have added the following to .htaccess:

RewriteCond %{QUERY_STRING} linkid=([0-9]*)$ [NC]
RewriteRule ^view.php$ [localhost...] [R]

Note - [R] is used instead of [R=301] to avoid permanent caching issues while in development, and obviously localhost will be replaced with the domain in deployment.

Anyway, this rule also works - unfortunately though what I've done is created an endless loop. When a view.php?linkid=x URL is accessed, it obviously redirects to /view/x/, which in turn is just a rewrite of view.php?linkid=x, and hence the endless loop.

I know there must be something I'm missing, so any help is greatly appreciated. Perhaps I'm going about this the wrong way? Basically, I just want to rewrite my old dynamic URL to a static one while also redirecting said old dynamic URL to the static one.

Thanks for any help.

g1smd

11:38 pm on Mar 12, 2009 (gmt 0)

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



There have been half-a-dozen threads this week with related discussions. Several other people are doing similar things on their sites.

You need for the redirect to fire only for direct client requests. To that end you need to examine THE_REQUEST when deciding whether to redirect or not.

The redirect must include the domain name in the target URL.

The redirect must be listed before the rewrite.

Note that [R] gives a 302 redirect, and you'll need [R=301]. You can get a LOT of search engine problems with a 302 redirect.

Every rule must end with [L].

NathanD

11:59 pm on Mar 12, 2009 (gmt 0)

10+ Year Member



Ok thanks, I think I understand - so in the RewriteCond I need to do something like:

RewriteCond %{THE_REQUEST},%{QUERY_STRING} bla bla,linkid=([0-9]*)$ [NC]

Correct? obviously where bla bla is checking the HTTP request header. I know that much, but I'm not sure exactly what I'm looking for?

Oh and I know about 302's and search engines, I'm just using [R] in development as to avoid browser caching.

NathanD

12:50 am on Mar 13, 2009 (gmt 0)

10+ Year Member



Ok after a bit of snooping around, I've got a working solution:

RewriteCond %{the_request} ^[A-Z]{3,9}\ /view\.php\?linkid=(.*)\ HTTP/
RewriteRule ^view.php$ [localhost...] [R,L]

This seems to work without even needing the %{query_string} condition.

Thanks for the help - and feel free to let me know if this is not the best solution (it works, but I'm not opposed to making things work better :)).

g1smd

12:53 am on Mar 13, 2009 (gmt 0)

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



Check the last dozen or so open threads in this forum, for the ones that discuss the correct usage of THE_REQUEST.

You absolutely cannot guess the syntax without risking bringing your whole site down, inaccessible to everyone.

THE_REQUEST will contain the full request made by the browser or bot, including query string.

There's no need to be looking explicitly at QUERY_STRING.

NathanD

1:03 am on Mar 13, 2009 (gmt 0)

10+ Year Member



It's ok, I'm only on an offline test server on my own PC (i.e. localhost) - guessing syntax isn't a concern ;)

Thanks though, I think I've got it.

jdMorgan

5:24 pm on Mar 13, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Speed up the RewriteCond pattern match, escape literal periods, and use a 301 redirect, not a 302!

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /view\.php\?linkid=([^\ ]*)\ HTTP/
RewriteRule ^view\.php$ http://localhost/view/%1/? [R=301,L]

Jim