URL redirections

URL redirections

URL redirections were obvious for me. That was before my husband asked me about the differences between redirecting within htaccess, php, or any other way. Sure I knew how to do it, but I never wondered about the differences between all the ways. So while understanding those will be my goal today, my favorite SEO expert (aka my husband) will explain you how to use the redirections in a proper SEO way (in french for now, soon translated).

HTTP Redirection codes
Before diving into the redirections, let’s have a look at the different HTTP codes used to perform a HTTP redirection. The whole 3xx range is dedicated to this job, but only 2 of them are commonly used :

  • 301 Moved Permanently : this means the page you’re trying to reach doesn’t exist anymore and will not resurrect in the future, but the content is available at the next location. The RFC2616 also says that there should be a short message with a link to the new location.
  • 302 Found : This is the code commonly used for “temporary redirect”

The other existing redirection codes (from Wikipedia ) :

  • 300 Multiple Choices : Indicates multiple options for the resource that the client may follow. It, for instance, could be used to present different format options for video, list files with different extensions, or word sense disambiguation.
  • 303 See Other : The response to the request can be found under another URI using a GET method.
  • 307 Temporary Redirect : the request should be repeated with another URI […], the request method should not be changed when reissuing the original request.

These 3 last codes are hardly used, and unless you know exactly what you’re doing I advise you to stick on 301 and 302 redirection codes.

How to do a redirection
There is more than one way to redirect a web page to another. The best way in my opinion is to use the HTTP headers to tell the client (well, a browser most of the time) that the page has moved. If you’re not able to do this, you can still tell it in the HTTP message, but it will let the browser decide if it can or wants to follow it or not.

I’ve created a test space on this website to try the redirections, so you can test it by yourself if you want to : http://amandine.aupetit.info/tests/redirections/

– Apache
In order to redirect a page to another within apache, you need mod_alias module installed. You can do it with mod_rewrite too, but this second module is better for for complicated rewrites and redirections, simple ones beeing bast handled with mod_alias.

The syntax is quite simple :

Redirect redirect_code /path/old_page /path/new_page

The redirect code will most of the time be 301 or 302; the path is the one that you will see in the URL after the domain name.
For example, in my test space, I want to redirect apacheredirect.html to finalpage.html. Those file are in /tests/redirections/ , so this is what I wrote in my .htaccess file (could have been in the vhost definition directly, that’s exactly the same) :

Redirect 301 /tests/redirections/apacheredirect.html /tests/redirections/finalpage.html

You can test the redirection here.
Truth is, I didn’t even have to create a real file named apacheredirect.html, the redirection would have work exactly the same way. That’s just for you to have a link to click on if you go in the test space 😉

Now, what happens when we ask the page http://amandine.aupetit.info/tests/redirections/apacheredirect.html ? Let’s telnet to see! (I know, I could see HTTP headers with a browser, Firefox with webdevelopper or any other cool way, but I love telnet because it is damn simple and I’m sure nothing comes between me and the information I want to see) :

$ telnet amandine.aupetit.info 80
Trying 88.190.40.18…
Connected to hosting.yellow-sub.net.
Escape character is ‘^]’.
GET /tests/redirections/apacheredirect.html HTTP/1.1
Host: amandine.aupetit.info

HTTP/1.1 301 Moved Permanently
Date: Sun, 01 Jul 2012 14:09:22 GMT
Server: Apache/2.2.14 (Ubuntu)
Location: http://amandine.aupetit.info/tests/redirections/finalpage.html
Vary: Accept-Encoding
Content-Length: 357
Content-Type: text/html; charset=iso-8859-1

301 Moved Permanently
<h1>Moved Permanently</h1>
The document has moved <a href=”http://amandine.aupetit.info/tests/redirections/finalpage.html”>here</a>.

<hr />

<address>Apache/2.2.14 (Ubuntu) Server at amandine.aupetit.info Port 80</address>
</body></html>

The first part of the answer is the HTTP header. We can see the 301 redirect code on the first line : “

HTTP/1.1 301 Moved Permanently”, then where we should go next on the 4th line : “Location: http://amandine.aupetit.info/tests/redirections/finalpage.html“. The message part tells the same, but we already had all the information.

To see the difference, let’s go to the finalpage :

$ telnet amandine.aupetit.info 80
Trying 88.190.40.18…
Connected to hosting.yellow-sub.net.
Escape character is ‘^]’.
GET /tests/redirections/finalpage.html HTTP/1.1
Host: amandine.aupetit.info

HTTP/1.1 200 OK
Date: Sun, 01 Jul 2012 14:12:50 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Sun, 01 Jul 2012 13:49:44 GMT
ETag: “fc0b1e-1f-4c3c4f42aea8e”
Accept-Ranges: bytes
Content-Length: 31
Vary: Accept-Encoding
Content-Type: text/html
X-Pad: avoid browser bug

You have been redirected here!

The HTTP code here is “200 OK“, which means the page exists, has been found, and that its content will be returned, and as announced, the message is the content of the file.

Great! Let’s try another redirection method now! 😉

– PHP
I’m picking PHP as an example here, but I guess every dynamic language used for the web has it’s own way to send a custom HTTP header line.
For PHP, here’s the syntax :

Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: finalpage.html" );

$ telnet amandine.aupetit.info 80
Trying 88.190.40.18…
Connected to hosting.yellow-sub.net.
Escape character is ‘^]’.
GET /tests/redirections/phpredirection.php HTTP/1.1
Host: amandine.aupetit.info

HTTP/1.1 301 Moved Permanently
Date: Sun, 01 Jul 2012 14:18:34 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.15
Location: finalpage.html
Vary: Accept-Encoding
Content-Length: 0
Content-Type: text/html

If you omit the first Header line, you will get a “302 Found” HTTP code but a “Location” header nonetheless :

$ telnet amandine.aupetit.info 80
Trying 88.190.40.18…
Connected to hosting.yellow-sub.net.
Escape character is ‘^]’.
GET /tests/redirections/phpredirection.php HTTP/1.1
Host: amandine.aupetit.info

HTTP/1.1 302 Found
Date: Sun, 01 Jul 2012 14:19:03 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.15
Location: finalpage.html
Vary: Accept-Encoding
Content-Length: 0
Content-Type: text/html

This is still a redirection though.
The only noticeable difference you can see between a Apache redirect and a PHP redirect, except from some other headers that we’re not interested in today, is that PHP doesn’t provide a HTTP message with the redirection. This is against the RFC, but the message isn’t really useful for browsers anyway, so this is virtually the same. (Well ok, the “Location” header is a full URL in the Apache redirection, and a relative one in the PHP redirection, but I could have written the full URL in the php file to get the full URL in the Location header.)

– HTML
I’ve created a html file with this content :

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<meta http-equiv=”refresh” content=”0;url=finalpage.html”>
</head>
<body>
You’re going to be redirected…
</body>
</html>

The file is here : http://amandine.aupetit.info/tests/redirections/htmlredirect.html
Let’s try it with telnet 😉

$ telnet amandine.aupetit.info 80
Trying 88.190.40.18…
Connected to hosting.yellow-sub.net.
Escape character is ‘^]’.
GET /tests/redirections/htmlredirect.html HTTP/1.1
Host: amandine.aupetit.info

HTTP/1.1 200 OK
Date: Sun, 01 Jul 2012 14:43:45 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Sun, 01 Jul 2012 14:42:03 GMT
ETag: “fc0b2b-d0-4c3c5af468b8e”
Accept-Ranges: bytes
Content-Length: 208
Vary: Accept-Encoding
Content-Type: text/html
X-Pad: avoid browser bug

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<meta http-equiv=”refresh” content=”0;url=finalpage.html”>
</head>
<body>
You’re going to be redirected…
</body>
</html>

The redirection code here is the same as a non redirected page : 200 OK. The header doesn’t mention any “Location” where we should go next, in fact this information is shown only in the HTTP message part with a meta tag : “<meta http-equiv=”refresh” content=”0;url=finalpage.html”>
If you’re fast enough, you can actually see the redirection in your browser, because it has to get and load the whole page before doing the redirection and go get the second page. In most cases, that will work. It’s surely slower and not optimized, but it works!

But why does it work? From the W3C HTML 4.01 specification :

META and HTTP headers
The http-equiv attribute can be used in place of the name attribute and has a
special significance when documents are retrieved via the Hypertext Transfer
Protocol (HTTP). HTTP servers may use the property name specified by the
http-equiv attribute to create an [RFC822]-style header in the HTTP response.

This means that the browser will behave as if it had received a “Refresh: 0;url=finalpage.html” HTTP header. The Refresh header was created by Netscape in the very early days of the internet and is almost considered as a standard since then, as almost every browser supports it nowadays.
Surprisingly, I would have thought after learning this that we could rewrite the Location header from HTML in the same way, but it just doesn’t work :

<meta http-equiv=”Location” content=”URL=http://amandine.aupetit/info/tests/redirect/finalpage.html” />

The file is here : http://amandine.aupetit.info/tests/redirections/htmlredirect2.html , and you see that it doesn’t redirect. From what I read, some browsers used to support it but it has now been deprecated and abandonned.

  • Javascript

Instead of adding a meta tag, you can add some javascript lines to your html page to achieve the redirect :

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<script type=”text/javascript”>
<!–
window.location = “finalpage.html”
//–>
</script>

</head>
<body>
You’re going to be redirected…
</body>
</html>

The page is here : http://amandine.aupetit.info/tests/redirections/javascriptredirect.html

$ telnet amandine.aupetit.info 80
Trying 88.190.40.18…
Connected to hosting.yellow-sub.net.
Escape character is ‘^]’.
GET /tests/redirections/javascriptredirect.html HTTP/1.1
Host: amandine.aupetit.info

HTTP/1.1 200 OK
Date: Sun, 01 Jul 2012 14:52:35 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Sun, 01 Jul 2012 14:49:50 GMT
ETag: “fc0b30-f9-4c3c5cb1bca10”
Accept-Ranges: bytes
Content-Length: 249
Vary: Accept-Encoding
Content-Type: text/html
X-Pad: avoid browser bug

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<script type=”text/javascript”>
<!–
window.location = “finalpage.html”
//–>
</script>

</head>
<body>
You’re going to be redirected…
</body>
</html>

As you can see, the headers are similar to the html redirection ones. The browser is performing the redirect in the same way, and you can also see it.
With a classic web browser, this will work too, but maybe with a slightest efficiency percentage than a html redirect, because not all browsers support javascript (ok almost nobody uses a text web browser, but they exist anyway!)

Conclusion
In short, HTTP provides a native way to achieve a redirection, so you should just use it if you can. Other ways will work but try to avoid them as they are slower and depends on the browser.

Comments are closed.
ac764633e5015ba92feb2eb3e8252fccZZZZZZZZZZZZZZZZ