19.8. Redirecting to a Different Location

Problem

You need to tell the client's browser to look elsewhere for a page.

Solution

Instead of a normal header, just issue a location redirect and exit. Don't forget the extra newline at the end of the header.

$url = "http://www.perl.com/CPAN/";
print "Location: $url\n\n";
exit;

Discussion

Sometimes your CGI program doesn't need to generate the document on its own. It only needs to tell the client at the other end to fetch a different document instead. In that case, the HTTP header needs to include this directive as a Location line followed by the URL you want to send them to. Make sure to use an absolute URL, not a relative one.

The direct and literal solution given above is usually sufficient. But if you already have the CGI module loaded, use the redirect function. You might use this code if you are building and setting a cookie, as shown in Example 19.4 .

Example 19.4: oreobounce

#!/usr/bin/perl -w
# 

oreobounce - set a cookie and redirect the browser
use CGI qw(:cgi);

$oreo = cookie( -NAME    => 'filling',
                -VALUE   => "vanilla crиme",
                -EXPIRES => '+3M',    # M for month, m for minute
                -DOMAIN  => '.perl.com');

$whither  = "http://somewhere.perl.com/nonesuch.html";

print redirect( -URL     => $whither,
                -COOKIE  => $oreo);

That would produce:





Status: 302 Moved Temporarily








Set-Cookie: filling=vanilla%20cr%E4me; domain=.perl.com; 








    expires=Tue, 21-Jul-1998 11:58:55 GMT








Date: Tue, 21 Apr 1998 11:55:55 GMT








Location: http://somewhere.perl.com/nonesuch.html








Content-Type: text/html








B<<blank line here>>



Example 19.5 is a complete program that looks at the client browser name and redirects it to a page in Eric Raymond's Jargon File that talks about the user's browser. It's also a nice example of a different approach to building a switch statement in Perl.

Example 19.5: os_snipe

#!/usr/bin/perl
# 

os_snipe - redirect to a Jargon File entry about current OS
$dir = 'http://www.wins.uva.nl/%7Emes/jargon';
for ($ENV{HTTP_USER_AGENT}) {
    $page  =    /Mac/            && 'm/Macintrash.html'
             || /Win(dows )?NT/  && 'e/evilandrude.html'
             || /Win|MSIE|WebTV/ && 'm/MicroslothWindows.html'
             || /Linux/          && 'l/Linux.html'
             || /HP-UX/          && 'h/HP-SUX.html'
             || /SunOS/          && 's/ScumOS.html'
             ||                     'a/AppendixB.html';
}
print "Location: $dir/$page\n\n";

The os_snipe program shows a good use of dynamic redirection, because you don't always send every user to the same place. If you did, it would usually make more sense to arrange for a static redirect line in the server's configuration file, since that would be easier on the web server than running a CGI script for each redirection.

Telling the client's browser that you don't plan to produce any output is not the same as redirecting nowhere:

use CGI qw(:standard);
print header( -STATUS => '204 No response' );

That produces this:





Status: 204 No response








Content-Type: text/html








<blank line here>



Use this, for instance, when the user will submit a form request but you don't want their page to change or even update.

It may seem silly to provide a content type and then no content, but that's what the module does. If you were hand-coding this, it wouldn't be required.

#!/bin/sh

cat <<EOCAT
Status: 204 No response
 
EOCAT





See Also

The documentation for the standard CGI module


Previous: 19.7. Formatting Lists and Tables with HTML Shortcuts Perl Cookbook Next: 19.9. Debugging the Raw HTTP Exchange
19.7. Formatting Lists and Tables with HTML Shortcuts Book Index 19.9. Debugging the Raw HTTP Exchange