Forum Moderators: phranque

Message Too Old, No Replies

Redirect to new domain where old url contains ?

         

macmumma

8:56 pm on Oct 14, 2015 (gmt 0)

10+ Year Member



I have developed a new joomla site and have the old domain parked on the new domain however to keep external links working I would like to have 301 redirects from individuals pages to the closest related page. The redirects are in the new domains .htaccess file.

I am trying to redirect
http://www.example.com/index.php?s=products&cat=1
to
http://example.com/index.php/products/cornices

I have found instructions on how to replace the ? and tried the following however I can see how this would cover the domain change. The following code is causing an internal server error.

RewriteCond %{QUERY_STRING}^?s=products&cat=1$
RewriteRule ^index\.php$http://www.example.com/? [R=301,L]

Any assistance really appreciated

[edited by: engine at 11:16 am (utc) on Oct 15, 2015]
[edit reason] please use example.com [/edit]

whitespace

12:29 pm on Oct 15, 2015 (gmt 0)

10+ Year Member Top Contributors Of The Month



You appear to be missing a delimiter (ie a space) between the arguments in both the RewriteCond and RewriteRule directives?

The %{QUERY_STRING} variable does not actually contain the "?" character.

The RewriteRule substitution does not match the required target URL as mentioned in the lines above... "www" instead of bare domain and missing any URL path.

macmumma

7:19 pm on Oct 15, 2015 (gmt 0)

10+ Year Member



Thanks for your response, however I am aware that I have not got the rewrite rule correct for this situation, however I do not know how to structure the code for this situation.
The example above should be

I am trying to redirect
http://www.example.com/index.php?s=products&cat=1
to
[newexample.com...]

I would really appreciate an example that would cover the situation I have. I am not a coder and am limited in my understanding of the required code.

Thanks

lucy24

9:12 pm on Oct 15, 2015 (gmt 0)

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



I don't see where you're capturing. It looks as if what you're trying to do is something like
RewriteCond %{QUERY_STRING} param1=([^&]+)&param2=([^&]+)
RewriteRule ^(index\.php)?$ http://www.example.org/%1/%2? [R=301,L]
That's not the exact rule, of course, but that's the concept. Each capture from the query string becomes % in the target. The ? at the end of the target is what prevents the query from being reappended.

This is assuming your query strings at the old site always come in the same order. If they could be mixed up, like param2 before param1, or some other parameter between the two, you'll need to make a group of separate rules. Unfortunately you can't put each parameter name into a separate RewriteCond; you can only capture from the very last Condition before the Rule.

For future reference note that you can use any tld, including ones you've made up --example.com, example.org, example.de, example.xyz etcetera-- but it has to be the exact word "example". Yes, you can say "example.old" and "example.new" if that's easier to follow.

macmumma

10:10 pm on Oct 15, 2015 (gmt 0)

10+ Year Member



Thanks for the tip on the use of the URL

Would it be possible to provide an example that would create a 301 redirect from

http://www.example.old/index.php?s=products&cat=1
to
http://example.new/index.php/products/cornices

I am not familiar with the code in the param1=([^&]+) to know where to replace the code with my example.

Thanks

lucy24

11:23 pm on Oct 15, 2015 (gmt 0)

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



The element [^&]+ is the key to capturing from a query string: it means "capture up to the next & and no further". (In Regular Expressions, ampersands need no special handling or escaping. This isn't html.) I said + rather than * because you probably want a separate rule for empty parameters, assuming they even exist.

So the rule would be
RewriteCond %{QUERY_STRING} \bs=([^&])&cat=([^&])
RewriteRule ^index\.php http://example.new/index.php/%1/ ....
Whoops! Where'd the "cornices" come from? Obviously the string "cornices" is not deducible from the string "1", so we need to get more complicated.

How many values can "cat" have? * If the number is large, is it your own server? (The one for example.old. It doesn't matter about example.new)

If there are only a few possible values for "cat"-- say, less than ten-- then you can make individual rules with RewriteConds looking at "cat=1" "cat=2" etcetera. If there are many possibilities, you can either use a RewriteMap (only possibly if it's your own server) or rewrite to a php script that does the lookup.

The locution \bs is just in case you have parameters named "this" or "houses" or anything else ending in "s". If you have very weird parameter names, you'd need to say
(?:^|&)
but let's not borrow trouble.

But, as long as we're here... What's that "index.php" for in the target? It would seem to defeat the point of the new, pretty-looking URL. I assume you're going to be rewriting at the far end, so why do you need an explicit "index.php" at all?


* Apart from Truffles and Greebo, that is.

macmumma

12:07 am on Oct 16, 2015 (gmt 0)

10+ Year Member



Thanks for your detailed response, however I am still having trouble.

Yes there are only about 7 to redirect, the index.php is created by the content management system used to develop the website. I do not have access to the old domains hosting as it is parked on the new domain. The .htaccess file is sitting in the root directory of the new domain. I have tried the rewrite as

RewriteCond %{QUERY_STRING} \bs=([^&])&cat=1$
RewriteRule ^index\.php $http://www.example.new/index.php/products/cornices? [R=301,L]

But I am getting redirected to the home page of that site "http://www.example.new/index.php" rather than to the individual page "http://www.example.new/index.php/products/cornices". The URL that displays in the browser is the original URL "http://www.example.old/index.php?s=products&cat=1

Am I missing something?

lucy24

1:00 am on Oct 16, 2015 (gmt 0)

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



I do not have access to the old domains hosting as it is parked on the new domain.

Uh-oh, it's no more than 24 hours since someone else used the term "parked" and I had to lean on them to explain what they mean. Did you change the old domain's DNS to point to the same physical location as the new domain? Not ideal, if so, but we'll have to work with it. The point is simply that requests for example.old have to go somewhere -- if they didn't, you would get a message from your browser saying "I can't find the site" -- so any htaccess rules concerning example.old need to go in that place.

I am getting redirected to the home page of that site "http://www.example.new/index.php" rather than to the individual page "http://www.example.new/index.php/products/cornices". The URL that displays in the browser is the original URL

That's not a redirect, it's a rewrite. This is an important distinction to understand: A redirect is an instruction to the browser to make a new request; the address bar will change. A rewrite is behind-the-scenes activity that the visiting browser doesn't know about, such as bringing up content from
index.php?a=something&b=something-else&c=third-thing
while the address bar says
/something/something-else/third-thing
(Your CMS probably handles this part internally.)

Here it looks as if the original URL is displaying the content of
example.new/
in response to requests for
example.old/
If I'm guessing correctly that example.old/ and example.new/ now lead to the same physical directory, then you need another RewriteCond to say
RewriteCond %{HTTP_HOST} example\.old
RewriteCond %{QUERY_STRING} etcetera as before
... and this rule (and all the others for the various values of "cat") has to go before any rules that are specific to the new site.

macmumma

1:34 am on Oct 16, 2015 (gmt 0)

10+ Year Member



I really appreciate the detail of your explanations, yes the DNS is pointed to the location of the new website. There is no hosting associated with the old domain so no where to put an htaccess file associated with the old domain. I would prefer to do a 301 redirect, however from what I have read it cannot handle the encoded characters. I would prefer users to not see the old domain in the URL.

I have added the line above but still no luck, I am still ending up at the homepage.

?

lucy24

2:42 am on Oct 16, 2015 (gmt 0)

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



I would prefer to do a 301 redirect, however from what I have read it cannot handle the encoded characters.

Dang, you keep throwing new stuff at us. What encoded characters? And what has this whole thread been about, if not redirecting?

If you're using a CMS, there is presumably an htaccess already in place, using mod_rewrite. Where are you putting the new rules, in relation to the built-in stuff?

Try this. At the very beginning of the mod_rewrite section of your htaccess-- right after the line "RewriteEngine on" --say something like this:
RewriteCond %{HTTP_HOST} example\.old
RewriteRule gizmo http://example.new/foobar [R=301,L]
In your browser, request
example.old/gizmo.html
Where do you end up?Page content doesn't matter (yet); I'm only concerned with the address bar. (If you actually do have pages named "gizmo" and/or "foobar", make up something else.)

macmumma

8:51 am on Oct 16, 2015 (gmt 0)

10+ Year Member



I am sorry if I have added confusion, yes the above code redirected to the new domain/foobar and produced a not found message.
I don't really care how it is done I just wanted users who had links to the old pages on the old domain to be delivered the new pages on the new domain maintaining as much page ranking as possible for search engine ranking.
I have obviously used the wrong term for the characters that are causing the normal redirect methods I have used in the past not to work i.e. ? and = characters.

lucy24

8:28 pm on Oct 16, 2015 (gmt 0)

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



yes the above code redirected to the new domain/foobar and produced a not found message

OK, good, that was the rock-bottom test: is mod_rewrite working as intended? Yes, it is.

If you're talking about the ? and = that occur as part of an ordinary query string, you need not be concerned about those.

Now then! Stay at the very beginning of the mod_rewrite section of your htaccess file. (Exception: If you happen to have any RewriteRules that involve access control-- the ones with [F] flag-- then any new rules should go after those. No point in redirecting people who are just going to get locked out anyway.)

And now try one of the new rules. Sticking with your own example of
from
http://www.example.old/index.php?s=products&cat=1
to
http://example.new/index.php/products/cornices
I forgot to ask if "s" can have values other than "products". I'm assuming it can, in which case the rule looks like this
RewriteCond %{HTTP_HOST} example\.old
RewriteCond %{QUERY_STRING} cat=1
RewriteCond %{QUERY_STRING} \bs=([^&]+)
RewriteRule ^(index\.php)?$ http://example.new/%1/cornices [R=301,L]
This is assuming the possible values of "cat" are never more than one digit. If there's a possibility of "cat=17" or similar, say cat=1\b with word-ending anchor. Conversely, if "products" is the only possible value of "s" (or, at least, the only possible value when cat=1) then you don't need to capture anything; just use the literal text "s=products" without parentheses.

Now request
example.old/index.php?s=products&cat=1
and verify that you've been redirected (address bar changes) to
example.new/index.php/products/cornices
If yes, try
example.old/index.php?s=any-old-garbage&cat=1
and verify redirect to
example.new/index.php/any-old-garbage/cornices
If no, try omitting the ^ and $ anchors from the rule. (It shouldn't make any difference in htaccess, but let's make sure.)

So far, page content doesn't matter; the first step is to ensure that the redirect is taking place.

macmumma

9:57 pm on Oct 16, 2015 (gmt 0)

10+ Year Member



Hallelujah! Thank you so much for your perseverance with me.

The final code I used was
RewriteCond %{HTTP_HOST} example\.new
RewriteCond %{QUERY_STRING} cat=1
RewriteCond %{QUERY_STRING} \bs=([^&]+)
RewriteRule ^(index\.php)?$ http://example.new/index.php/%1/cornices [R=301,L]
RewriteCond %{QUERY_STRING} cat=2
RewriteCond %{QUERY_STRING} \bs=([^&]+)
RewriteRule ^(index\.php)?$ http://example.new/index.php/%1/domes [R=301,L]

The second rule is working as well.
There is still a trailing ?s=products&cat=1 on the end of the URL. However it does not seem to be having an impact.
Thanks so much

lucy24

1:23 am on Oct 17, 2015 (gmt 0)

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



Oops, my bad, I misplaced the ? that needs to go at the end of the target. (We had it earlier in the thread; it just got lost.) It means "get rid of the existing query string, if any". So every target will look like
http://example.new/blahblahblah?
with final question mark.

RewriteCond %{HTTP_HOST} example\.new
Unless something has gotten seriously messed up, this should be "example\.old" And the condition has to be attached to each rule. (Each RewriteRule is an island. Conditions apply only to the current rule.) This is a non-fatal error, because requests aimed at example.new will fail the assorted query-string tests-- but it's more work for the server than the quick-and-brutal hostname test.