Book HomePerl CookbookSearch this book

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 ShortcutsPerl CookbookNext: 19.9. Debugging the Raw HTTP Exchange
19.7. Formatting Lists and Tables with HTML ShortcutsBook Index19.9. Debugging the Raw HTTP Exchange

Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.