Welcome to WebmasterWorld Guest from 54.198.210.67

Forum Moderators: Ocean10000 & incrediBILL & phranque

Message Too Old, No Replies

.htaccess 301 to new website help

redirect not working as it should

     
2:43 am on Apr 2, 2014 (gmt 0)

Junior Member

5+ Year Member

joined:Jan 28, 2009
posts: 68
votes: 0


My site has always been used without the www, with a 301 redirect from www to non-www.

I have now changed my site's domain.

All works well with the new domain.

The old domain has the following .htaccess file:

Options +FollowSymLinks 
RewriteEngine on
#
RewriteCond %{HTTP_HOST} !^www\.new_site\.com
RewriteRule (.*) http://new_site.com/$1 [R=301,L]


And that works OK for redirecting old_site.com to new_site.com ; but if someone attempts to go to www.old_site.com, they see the old domain with www in the address window and the new site displays without CSS or pictures.

What have I done wrong with that .htaccess file?

Any help appreciated.
6:26 am on Apr 2, 2014 (gmt 0)

Administrator

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Aug 10, 2004
posts:11073
votes: 106


if you do an nslookup of old_site.com and www.old_site.com do they resolve to the same IP address?
does the VirtualHost configuration for both hostnames specify the same document root directory?
7:13 am on Apr 2, 2014 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:14251
votes: 551


What have I done wrong with that .htaccess file?

Nothing. It's a DNS problem. Do the old and new domains live on the same server? Same userspace or equivalent?

if someone attempts to go to www.old_site.com, they see the old domain with www in the address window and the new site displays without CSS or pictures.

This is interesting, though it may disappear once the dns issue is sorted out. When you say "the new site displays" do you mean that they see the old URL but the content of the new site? Or did you mean the old site? Are all the physical files for non-page material still in place? (May as well remove them, if so, because search engines ask for them surprisingly often.)

Oh, wait. Are both domains still active? That is, if you commented-out the redirect would you be able to reach the old domain? You're not pointing both names' dns to the same physical place are you?
8:45 am on Apr 2, 2014 (gmt 0)

Junior Member

5+ Year Member

joined:Jan 28, 2009
posts: 68
votes: 0


Yessss! Thank you! It was indeed a DNS problem, as I had mistakenly pointed the A-record of the old site to the new site's IP address, instead of the IP that hosts the .htaccess redirect file.

It works now.

In fact, it is very strange that it worked at all before... that's what had me confused.
12:56 pm on Apr 2, 2014 (gmt 0)

Administrator

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Aug 10, 2004
posts:11073
votes: 106


you should have a hostname canonicalization redirect configured on your new server as well.
4:08 pm on Apr 2, 2014 (gmt 0)

Junior Member

5+ Year Member

joined:Jan 28, 2009
posts: 68
votes: 0


Thanks; I think I do already:

RewriteCond %{HTTP_HOST} ^www.new_site.com [NC] 
RewriteRule ^(.*)$ http://new_site.com/$1 [L,R=301]
4:15 pm on Apr 2, 2014 (gmt 0)

Senior Member

WebmasterWorld Senior Member g1smd is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:July 3, 2002
posts:18903
votes: 0


You should point both DNS at the new hosting and install this code on the new host:

Options +FollowSymLinks
RewriteEngine on
#
RewriteCond %{HTTP_HOST} !^(example\.com}?$
RewriteRule (.*) http://example.com/$1 [R=301,L]


where "example" is the new hostname.

This will resolve all non-canonical hostname requests without needing separate hosting.

[edited by: phranque at 10:52 pm (utc) on Apr 2, 2014]
[edit reason] the typo above is discussed below, so leaving as is [/edit]

7:01 pm on Apr 2, 2014 (gmt 0)

Junior Member

5+ Year Member

joined:Jan 28, 2009
posts: 68
votes: 0


g1smd thank you, much appreciated. Where can I find the meaning of that code? E.g. what does the backslash after the hostname do, why the brackets, etc.? I don't quite like implementing policies that I don't fully understand.
10:11 pm on Apr 2, 2014 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:14251
votes: 551


I don't quite like implementing policies that I don't fully understand.

An admirable sentiment :)

It's not a backslash after the hostname; it's a backslash before the following period. Here's a walkthrough since you ask*:
RewriteCond %{HTTP_HOST} !^(example\.com}?$
RewriteRule (.*) http://example.com/$1 [R=301,L]

Piece by piece:
RewriteCond

Set this aside for now. mod_rewrite works on a system of "two steps forward, one step back": it first looks at the rule itself. Only if the rule can potentially apply does it also look at the condition(s).

RewriteRule

"Here's what will happen".
In mod_rewrite, and certain other Apache mods, a space has syntactic meaning. There's no other punctuation, no braces or "function" labels.

(.*)

First part of rule: the PATTERN.

If there's a request for .* then capture it. Both of these characters have special meanings in Regular Expressions (any flavor, not just mod_rewrite, not just Apache).
The . means "any one character, including spaces". Spaces don't occur in URLs-- but they do occur in other aspects of the request, where they need special handling.
The * means "zero or more of what came before". If the rule is in an htaccess file located in your root directory-- the normal place for htaccess files if you use them-- then a request for the root is seen as "" (nothing). Regular Expressions start as soon as they can and continue as long as they can, so the form .* will cover the entire thing.
Finally the () parentheses mean "capture this part for later re-use". Parentheses can be used for other things, but they always capture too unless you've explicitly told them not to.

http://example.com/$1

Second part of rule: the TARGET. If the pattern matches, then point them to http://example.com/ plus
$1

whatever they asked for in the first place. In targets only, $ followed by a single numeral means "reuse this captured group from the pattern". There can be up to 9, counted from left to right. If there are nested parentheses, count from the opening parenthesis only.

[R=301,L]

Optional final part of a rule: the FLAGS.
Any time a target contains the full protocol-plus-hostname, it turns into a 302 temporary redirect. (This applies to other areas too, such as ErrorDocument directives, not only to mod_rewrite.) To change it to 301 permanent, you have to say so explicitly.

In addition, you need an [L] flag meaning "We're done with mod_rewrite this time around". Some actions carry an implied [L]; a redirect doesn't, so again you have to say so explicitly.

And now we get to the condition. If there's more than one, they are read from top to bottom.

The form .* obviously matches all requests everywhere. So if you don't include a condition, requests will go around in circles forever, winding up with an error message from your browser. Conditions have a little more syntactic variation than rules, but this is the most common pattern.

RewriteCond %{HTTP_HOST}

"If the requested hostname is..."

!^(example\.com)?$

-- or, in this case, "is not..." That's what the leading ! means. Unlike other stuff we've met so far, the ! locution is specific to Apache. (It occurs elsewhere, but is not a property of Regular Expressions as such.)

:: bzzt! typo! bzzt! typo! ::

Oh, lord. I remember one time I made this identical typo myself, and then various other people cut-and-pasted, and poor phranque had to spend all day cleaning up the thread.

^

^ "opening anchor" means "the specified text has to come at the very beginning of the element I'm looking at", here the hostname. So "example" matches but "www.example" doesn't.
(example\.com)

Remember I said that parentheses have uses besides capturing? Here they mean that the contents of the parentheses are to be treated as a package; anything that comes afterward applies to the whole package.
\.

I said before that a . in Regular Expressions means "any one character". So if you mean an actual, literal period, it has to be "escaped". That's the meaning of the \ backslash. It occurs in other situations, such as
\(

"an actual, literal parenthesis" or
\ 

"an actual, literal space" but it's most important with periods. Consider the difference between "1.2" and "1\.2".

(example\.com)?

The question mark also has a special meaning: "the immediately preceding character-- or, here, the whole part in parentheses-- is optional". So it means "the hostname starts with 'example.com' or starts with nothing".
$

One more special character. In patterns only, the $ is a closing anchor. It means "the part I'm looking at has to end this way".

So, all together:
!^(example\.com)?$

"The part I'm looking at-- which we've already specified is the HTTP_HOST-- is not exactly 'example.com' or exactly nothing." The "exactly nothing" part has to do with ancient browsers and/or certain HTTP/1.0 requests that don't include a hostname at all. By convention, these are allowed in, although if you really hate proxies you could omit the parentheses and question mark, so the only condition is "exactly example.com".

Some conditions have flags of their own, but here there aren't any, so we're all done.

All together:
"If there is a request for anything at all, then if the requested hostname is anything other than 'example.com' or nothing, then send them around to 'example.com', keeping the rest of the request in its original form."

Whew.


* And then, whenever anyone else asks in the next couple of years, we can point them to this post.
10:23 pm on Apr 2, 2014 (gmt 0)

Junior Member

5+ Year Member

joined:Jan 28, 2009
posts: 68
votes: 0


Astounding explanation lucy24; a zillion thanks. If I understand well, the language of .htaccess is that of the dreaded Regular Expressions, which I never managed to grasp, but always needed somehow.
10:29 pm on Apr 2, 2014 (gmt 0)

Senior Member

WebmasterWorld Senior Member g1smd is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:July 3, 2002
posts:18903
votes: 0


Well spotted on my typo.

Yes, the } bracket immediately before the question mark should be a ) bracket.

There's only a three pixel difference between those two on my screen. Err, though that is three out of seven.
11:08 pm on Apr 2, 2014 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:14251
votes: 551


I didn't see it myself until I pasted into a text editor. Everything is more visible in 14pt Courier.

If I understand well, the language of .htaccess is that of the dreaded Regular Expressions

Some modules use Regular Expressions. mod_rewrite does all the time; mod_setenvif does optionally; mod_alias does if you're using RedirectMatch rather than vanilla Redirect.

You are also right to be wary of Regular Expressions, since you can seriously hurt yourself with an incorrectly used RegEx. Same as any other powerful tool ;)
 

Join The Conversation

Moderators and Top Contributors

Hot Threads This Week

Featured Threads

Free SEO Tools

Hire Expert Members