Previous Table of Contents Next


In Hour 23, "Complex Forms," you learned how to make your web browser remember information between web pages by using hidden fields in HTML. You must understand this process because you might need to pass information from one instance of a CGI program to another. The only way to do this is to store a piece of information with the browser.

Another way to store information with the browser is to use HTTP cookies. HTTP cookies are pieces of information passed between the browser and the CGI program during the HTTP connection. Using cookies can be a much more flexible method of storing information with a browser than using hidden HTML fields.

You can think of a cookie as a movie theater ticket. You can go to the theater ticket booth and obtain a ticket for a subsequent showing. You can then leave the theater, come back, buy some popcorn, and do anything else you'd like. When you're ready to see the movie, you present your ticket to the ticket-taker. The ticket-taker doesn't know how, when, or why you purchased the ticket, but as long as you have it, the ticket-taker will let you into the theater. The ticket entitles the bearer to admission to a subsequent show.

An HTTP cookie is simply an information packet that the CGI program asks the browser to hold. The packet can be reclaimed at any time by another CGI program or by the same program. Cookies are even passed back to the server when regular HTML pages are requested. The cookie can contain any kind of information: information about multipage web forms, visitation information, user preferences, and so on.

The cookie is transferred from the server to the browser whenever a CGI program requests that a cookie be created (see Figure 24.3); this process is called setting a cookie.

Figure 24.3. Cookie going to the browser from a CGI program.

The cookie can be later reclaimed by a CGI program to retrieve the information stored in the cookie, as illustrated in Figure 24.4.

Figure 24.4. Cookie being returned to the server by the browser.

Why Is a Cookie Called a Cookie?

In computing circles, cookie is a very old term. It refers to any piece of information passed between routines or programs that enables the holder of the cookie to perform some operation. Some kinds of cookies are called magic cookies because they contain data that's obscure and meaningful only to the sender and the receiver of the cookie. CGI cookies are not magic.

How to Make Cookies

To create a cookie, you can use a CGI function called cookie. The syntax of the cookie function that you're concerned with is as follows:

$cookie_object=cookie( -name => cookie_name,         # Optional

                       -value => cookie_value,

                       -expires => expiration_date,  # Optional

                       -path  => path_info,          # Optional


The cookie function takes arguments in a way you haven't seen yet, but that is quite common in Perl modules. Each argument in the call to cookie has a name, so you don't have to remember the order in which the arguments occur; they simply get named in whatever order you decide to use them.

When called with the first syntax, the cookie function returns a cookie, which should be stored in a scalar variable and can then be given to the CGI module's header function to be sent to the browser. The only required argument to create a cookie is the -value argument. The -name argument allows several cookies to be sent to the browser at one time, which can be retrieved individually or as a group. The -expires and -path arguments are discussed in the next section.

The header function in the CGI module takes care of actually transmitting the cookie to the browser. This means you must create the cookie, by using the cookie function, and then call the header function soon afterward. You shouldn't send any other kind of data to the browser until after the cookie and the header have been sent.

To create a cookie and send it to a browser in a CGI program, you can use a CGI program similar to this:

#!/usr/bin/perl -w

use CGI qw(:all);

use strict;

my $cookie=cookie(-name => 'Sample',

    -value => 'This cookie contains no MSG');

# Transmit the cookie to the browser

print header(-cookie => $cookie);

After the preceding snippet has run, a cookie called Sample is set on the browser. The cookie contains the information 'This cookie contains no MSG'.

Watch Out!

Actually, the cookie might not be set. Browsers can refuse to accept a cookie for many reasons. See "Problems with Cookies" later this hour.

To retrieve cookies from the browser in your CGI program, you use the same function—cookie. When called without any arguments, as shown in the following examples, cookie returns a list of cookies that the browser has for your server:

@cookie_list=cookie();   # Returns names of all cookies set


# Returns the value for a particular cookie


By default, after the cookie is set on the browser, it is returned to any CGI program that resides on the same server. That is, only the server that set the cookies can fetch those cookies. To view the Sample cookie created previously, you can use another CGI program:

#!/usr/bin/perl -wT

use CGI qw(:all);

use strict;

print header();  # Print out the standard header

print "<p>Sample's  value: ", cookie('Sample'), "</p>";

The preceding snippet uses cookie with one argument—the name of the cookie whose value you want to see. That value is retrieved and printed.

The browser should retain the cookie until the browser is terminated. When the browser is restarted, the cookie Sample will be gone. If you want to make a more permanent cookie, see "Long Term Cookies" later in this hour.

By the Way

Most browsers have an option to view the cookies as they're being set. In Netscape, you can find the cookie viewing options under the Preferences selection on the Advanced tab. In Internet Explorer, the selection appears on the Advanced tab of the Internet Options dialog, and a radio button controls whether you can view cookies as they're set.

Example: Using Cookies

For this example, you'll create a small program to allow the user using the web browser to set the color of the web page he or she is viewing. The program actually does several things at once:

  1. Checks for a change in the default background color by checking for program parameters.

  2. Sets a cookie on the browser with the correct background color.

  3. Sets the background color of the page to the correct color.

  4. Displays a CGI form, allowing you to change the color.

Listing 24.2 contains the color-changing program.

Listing 24.2. Complete Listing for ColorChanger

1:   #!/usr/bin/perl -w

2:   use strict;

3:   use CGI qw(:all);

4:   use CGI::Carp qw(fatalsToBrowser);

5:   my($requested_color, $old_color, $color_cookie)=("","");

6:   $old_color="blue";  # Default value

7:   # Is there a new color requested?

8:   if (defined param('color')) {

9:       $requested_color=param('color');

10:  }

11:  # What was the old color, if any?

12:  if (defined cookie('bgcolor')) {

13:      $old_color=cookie('bgcolor');

14:  }

15:  if ($requested_color and ($old_color ne $requested_color)) {

16:      # Set the cookie in the browser

17:      $color_cookie=cookie(-name => 'bgcolor',

18:                           -value => $requested_color);

19:      print header(-cookie => $color_cookie);

20:  } else {

21:      # Nothing's changed, no need to set the cookie

22:      $requested_color=$old_color;

23:      print header;

24:  }

25:  print<<END_OF_HTML;

26:  <html>

27:  <head>

28:  <title>Set your background color</title>

29:  </head>

30:  <body bgcolor="$requested_color">

31:  <form>

32:  <select name="color">

33:          <option value='red'>Red</option>

34:          <option value='blue'>Blue</option>

35:          <option value='yellow'>Yellow</option>

36:          <option value='white'>White</option>

37:  </select>

38:  <input type="submit" value="Set the color"/>

39:  </form>

40:  </body>

41:  </html>


Lines 7–10: If this program is called as the target of a CGI program, the param('color') function returns a defined value—a new color. Otherwise, it returns nothing, and $requested_color remains unset.

Lines 12–14: These lines check for a cookie named bgcolor; that cookie might or might not exist. If it does exist, it is stored in $old_color, which is the last screen color value that was saved to a cookie.

Lines 15–19: If the color has changed (the cookie value doesn't match the new value), a new cookie needs to be set with the new value.

Lines 20–24: Otherwise, a plain header is printed without a cookie. Remember: The browser will retain the previous cookie indefinitely.

Lines 25–42: These lines create a standard HTML form. Note line 30, however; on this line, the color gets substituted into the HTML output.

Restricting Cookies

It's also possible to restrict a cookie's allowed return destinations. By default, when you create a cookie, that cookie is returned to any URL on that web site—including non-CGI URLs. For example, consider an automotive web site organized like the diagram in Figure 24.5.

Figure 24.5. Directory tree of a multiuse web site.

Having the sales CGI programs and the engineering CGI programs reside in different directories might make sense. If a sales CGI program were to set a cookie, the engineering CGI programs would pick it up, and vice versa. This result might not be desirable, and the people writing CGI programs for both sites need to coordinate to make sure they didn't reuse each other's cookie names.

To get around this problem, you can use the cookie function's -path option. It indicates the pathname—relative to the top of the URL—to which the cookie should be returned. For example, to send a cookie that will be returned only to the sales CGI programs, you could use this snippet:

# Cookie only visible to sales CGI programs

$cookie=cookie( -name => 'profile',

        -value => 'sedan,luxury,2-door',

        -path => '/cgi-sales');

print header(-cookie => $cookie);

By default, cookies are returned to every site on the server as though you had used the option -path=>'/'. To restrict the cookie to return to only one CGI program, you can use the CGI program's URL in the -path option:

# Return the cookie only to this program

$cookie=cookie( -name => 'profile',

        -value => 'sedan,luxury,2-door',

        -path => script_name() );

print header(-cookie => $cookie);

Remember that the script_name function in the CGI module returns the partial URL of the current CGI program. This effectively creates a cookie that will be returned only to the program that set the cookie on the browser.

    Previous Table of Contents Next
    © 2000- NIV