Redirect Site: Permanent Redirect with HTTP 301

This article describes how to properly redirect a web page using an HTTP 301 status code and Location header. The 301 status code is used to indicate that a page has permanently moved. Multiple techniques are presented with recommendations.

In order to redirect an out-of-print web page to another location, return the HTTP 301 status code and a location header in the HTTP response of the deprecated web page. The HTTP 301 response code will tell user-agents that the location has permanently moved. This is particularly useful for search engines like Google, which will carry over page rank to the new page if this status code is seen. If you do not need to indicate permanent displacement, you can accomplish redirection by setting a Location header in PHP or using Response.Redirect in ASP. The location header does the actual redirection to the new location, and can be used by itself.

HTTP headers are sent for every web page. If you want to see what HTTP headers look like for a particular page, visit Rex Swain’s HTTP Viewer. For advanced users, I would recommend you download the Firefox web browser and install Chris Pederick’s Web Developer Extensions. Then, use the Information->View Response Headers function. In scripts, HTTP headers must be sent before sending any page content, including white space, or else an error will result.

  • HTTP 301 Redirect in ASP-VBScript

<%@ Language=VBScript %>
<%
' Permanent redirection
Response.Status = "301 Moved Permanently"
Response.AddHeader "Location", "http://www.somacon.com/"
Response.End
%>

In Active Server Pages (ASP), Response.Redirect does not work the same as the code shown in the example. Response.Redirect will set the location header as shown, but it will set the status code to HTTP/1.1 302 Object moved instead. When you set the Location header with Response.AddHeader, the status code must be manually defined, otherwise it stays 200 OK.

If you send any page content prior to the headers, you will get an error like, “Response object error ‘ASP 0156 : 80004005′; Header Error; The HTTP headers are already written to the client browser. Any HTTP header modifications must be made before writing page content.”. Normally, you do not see this error even if there is content prior to the redirect, because page buffering is enabled by default in IIS. If you want to be sure there is no content being sent before the redirect, call Response.Flush just before it, disable page buffering with Response.Buffer = False, or configure IIS to disable page buffering. (Disabling buffering reduces performance.)

HTTP 301 Redirect in PHP

<?php
// Permanent redirection
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://www.somacon.com/");
exit();
?>

If you set the Location header by itself, PHP automatically sets the status code to HTTP/1.1 302 Found.

Note, if you attempt to send headers after content has been sent, you will get a warning like, “Warning: Cannot modify header information – headers already sent by …”. Watch out for empty lines and spaces between PHP open and close tags. ASP ignores these, but PHP does not.

  • HTTP 301 Redirect in ColdFusion

<CFHEADER statuscode="301" statustext="Moved Permanently">
<CFHEADER name="Location" value="http://www.somacon.com/">

Do not use a CFFLUSH command before the above tags, or in Application.cfm. This Coldfusion code was provided by Toll Free Forwarding.com.

  • HTTP 301 Redirect in Perl

#!/usr/bin/perl      -w
use strict;
print "Status: 301 Moved Permanantly\n";
print "Location: http://somewhere/page.htm\n\n";
exit;

As in PHP, if you do not supply the 301 code explicitly, Apache will send a “302 Found” status code. Note the subtle difference as compared to PHP. This example prints a “Status” header rather than an HTTP status code line. This is because you can not set the HTTP status code directly as you typically can in PHP. If you do, the server will return a 500 Internal Server Error, and the error log will show:

malformed header from script. Bad header=HTTP/1.1 301 Moved Permanently: /cgi/test.pl

The “Status” header is an alternative way of setting the HTTP status code. This is not passed to the browser directly, but the web server (Apache) converts it into a suitable HTTP status code. (The CGI specification does not allow directly setting the HTTP status code. Perl typically runs as a CGI, whereas PHP does not. For more information, see this PHP header FAQ or the PHP header function documentation.)

You must supply the carraige returns as specified above. Two carriage returns (\n\n) are needed after the last header, since they signify the end of the HTTP header and the beginning of content.

As in PHP, it is good practice to exit the script explicitly, otherwise, the Perl script continues executing. There should not be any print "Content-type: text/html\n\n"; or other output before printing these headers, or the headers will be printed as part of the content visible in the browser.

  • Redirection with mod_rewrite

The Apache module, mod_rewrite, is typically used to transform URLs from one form to another. It can also be used for permanent redirection. The rewriting rules can be placed in httpd.conf (for server-wide rules), or in .htaccess files (for directory-specific rules). Consider the following example that is in the .htaccess file of this website:

rewriteEngine on
rewriteRule ^contact\.php$ http://www.somacon.com/p2.php [R=permanent,L]

The first line tells Apache to turn the mod_rewrite engine on. The second line tells mod_rewrite to match requests where the URI is exactly contact.php. The ^ and $ match the beginning and end of the expression, respectively, and the \ is used to escape the period, which otherwise would match any character. After the match pattern is a space, and then the substitution. In this case, I want the server to substitute contact.php with http://www.somacon.com/p2.php.

In brackets are the comma-separated rule flags. The R=permanent flag tells Apache to issue a permanent redirect 301 response, with the location as the substituted URL. The L flag tells mod_rewrite that no other subsequent rules should be processed.

Note that I specified the full destination URL in the substitution, because otherwise mod_rewrite uses the short form of my hostname somacon.com. To avoid Google indexing issues, I’ve redirected all non-www traffic to the www prefixed host. I also redirect the default, index pages to the root directory. The rules to achieve this are as follows:

# redirect all non-www traffic
RewriteCond %{HTTP_HOST} ^somacon\.com$
RewriteRule ^.*$ http://www.somacon.com%{REQUEST_URI} [R=permanent,L]

# Redirect aliases of home page to the root website
rewriteRule ^index\.(php|html|htm) http://www.somacon.com/ [R=permanent,L]

I leave it up to the reader to understand this example by reading the mod_rewrite documentation. The mod_rewrite module offers a very powerful and effective way to perform redirection. It is preferable to use mod_rewrite over a server-side script. The drawback is the steep learning curve, requiring you to learn both its syntax and the syntax of regular expressions.

(Source: somacon.com)

Share and Enjoy:
  • Google Bookmarks
  • Facebook
  • Twitter
  • LinkedIn
  • StumbleUpon
  • Yahoo! Buzz
  • Digg
  • del.icio.us
  • Reddit
  • Print
  • PDF
  • email

Random Posts

Leave a Comment for Redirect Site: Permanent Redirect with HTTP 301