Redirecting to a Different Location (Perl Cookbook, 2nd Edition)

## 19.7. Redirecting to a Different Location

### 19.7.1. Problem

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

### 19.7.2. 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;

### 19.7.3. 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 in the Solution is usually sufficient, but if you already have the CGI module loaded, use the `redirect` function. You might use this code for 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);
>       use strict;

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

>       my $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
>     <<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 edition of the 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 (see Recipe 10.17).

#### 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 uses 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 more efficient 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 submits 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, the content type wouldn't be required, but the blank line still would be.

>     #!/bin/sh

>     cat <<EOCAT
>     Status: 204 No response

>     EOCAT

### 19.7.4. See Also

The documentation for the standard CGI module

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