< Day Day Up > |
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.
How to Make CookiesTo 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 --or-- # Returns the value for a particular cookie $cookie_value=cookie($cookie_name); 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 CookiesFor 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:
Listing 24.2 contains the color-changing program. Listing 24.2. Complete Listing for ColorChanger1: #!/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> 42: END_OF_HTML
Restricting CookiesIt'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. |
< Day Day Up > |