Recipe 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 = "";
print "Location: $url\n\n";

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  => '');
  my $whither  = "";
  print redirect( -URL     => $whither,
                  -COOKIE  => $oreo);

That would produce:

Status: 302 Moved Temporarily
Set-Cookie: filling=vanilla%20cr%E4me;; 
    expires=Tue, 21-Jul-1998 11:58:55 GMT
Date: Tue, 21 Apr 1998 11:55:55 GMT
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
  # os_snipe - redirect to a Jargon File entry about current OS
  $dir = '';
      $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.


cat <<EOCAT
Status: 204 No response


19.7.4 See Also

The documentation for the standard CGI module