📄 ch11_02.htm
字号:
<?label 11.2. Hidden Fields?><html><head><title>Hidden Fields (CGI Programming with Perl)</title><link href="../style/style1.css" type="text/css" rel="stylesheet" /><meta name="DC.Creator" content="Scott Guelich, Gunther Birznieks and Shishir Gundavaram" /><meta scheme="MIME" content="text/xml" name="DC.Format" /><meta content="en-US" name="DC.Language" /><meta content="O'Reilly & Associates, Inc." name="DC.Publisher" /><meta scheme="ISBN" name="DC.Source" content="1565924193L" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="CGI Programming with Perl" /><meta content="Text.Monograph" name="DC.Type" /></head><body bgcolor="#ffffff"><img src="gifs/smbanner.gif" alt="Book Home" usemap="#banner-map" border="0" /><map name="banner-map"><area alt="CGI Programming with Perl" href="index.htm" coords="0,0,466,65" shape="rect" /><area alt="Search this book" href="jobjects/fsearch.htm" coords="467,0,514,18" shape="rect" /></map><div class="navbar"><table border="0" width="515"><tr><td width="172" valign="top" align="left"><a href="ch11_01.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0" /></a></td><td width="171" valign="top" align="center"><a href="index.htm">CGI Programming with Perl</a></td><td width="172" valign="top" align="right"><a href="ch11_03.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0" /></a></td></tr></table></div><hr align="left" width="515" /><h2 class="sect1">11.2. Hidden Fields</h2><p><a name="INDEX-2250" /> <a name="INDEX-2,251" /> <a name="INDEX-2,252" /> <a name="INDEX-2,253" />Hiddenform fields allow us to store "hidden" information withina form; these fields are not displayed by the browser. However, youcan view the contents of the entire form, including the hiddenfields, by viewing its HTML source, using the browser's"<a name="INDEX-2254" /><a name="INDEX-2255" />View Source"option. Therefore, hidden fields are not meant for security (sinceanyone can see them), but just for passing session information to andfrom forms transparently. See <a href="ch04_01.htm">Chapter 4, "Forms and CGI"</a>, for moreinformation on forms and hidden fields.</p><p>Just to refresh your memory, here's a snippet containing ahidden field that holds a <a name="INDEX-2256" />session <a name="INDEX-2,257" />identifier:</p><blockquote><pre class="code"><FORM ACTION="/cgi/program.cgi" METHOD="POST"><INPUT TYPE="hidden" NAME = "id" VALUE = "e07a08c4612b0172a162386ca76d2b65">..</FORM></pre></blockquote><p>When the user presses the submit button, the browser encodes theinformation within all the fields and then passes the information tothe server, without differentiating the hidden fields in any manner.</p><p>Now that we know how hiddenf<a name="INDEX-2258" /><a name="INDEX-2259" />ields work,let's use them to implement a very simple application thatmaintains state information between invocations of multiple forms.And what better example to illustrate hidden fields than a shoppingcart application? See <a href="ch11_02.htm#ch11-44756">Figure 11-1</a>.</p><a name="ch11-44756" /><div class="figure"><img width="481" src="figs/cgi2.1101.gif" height="234" alt="Figure 11-1" /></div><h4 class="objtitle">Figure 11-1. The shoppe.cgi welcome page</h4><p>The shopping cart application we'll discuss is ratherprimitive. We don't perform any database lookups for productinformation or prices. We don't accept credit card numbers orpayment authorization. Our main goal in this section is to understandstate maintenance.</p><p>How does our application work? A typical shopping cart applicationpresents the user with several features, namely the ability to browsethe catalog of products, to place products in the cart, to view thecontents of the cart, and then finally to check out.</p><p>Our first goal is to create a <a name="INDEX-2261" />unique session identifier, right fromthe very beginning. Thus, the user must start at a dynamic web page,not a static one. Our welcome page is this:</p><blockquote class="simplelist"><p><em class="emphasis">http://localhost/cgi/shoppe.cgi</em></p></blockquote><p>In fact, this one CGI script handles all of the pages. It creates asession identifier for the user, appends it as a<a name="INDEX-2262" /><a name="INDEX-2263" />query stringto each link, and inserts it as a hidden field to each form. Thus,the links that appear on the bottom of each page look like this:</p><blockquote><pre class="code">shoppe.cgi?action=catalog&id=7d0d4a9f1392b9dd9c138b8ee12350a4shoppe.cgi?action=cart&id=7d0d4a9f1392b9dd9c138b8ee12350a4shoppe.cgi?action=checkout&id=7d0d4a9f1392b9dd9c138b8ee12350a4</pre></blockquote><p>The catalog page is shown in <a href="ch11_02.htm#ch11-54115">Figure 11-2</a>.</p><a name="ch11-54115" /><div class="figure"><img width="481" src="figs/cgi2.1102.gif" height="288" alt="Figure 11-2" /></div><h4 class="objtitle">Figure 11-2. The shoppe.cgi catalog page</h4><p>Our script determines which page to display by looking at the valueof the <em class="emphasis">action</em> parameter. Although users willtypically move from the catalog to the cart to the checkout, they arefree to move around. If you try to check out before you select anyitems, the system will ask you to go back and select items (but itwill remember your checkout information when you return!).</p><p>Let's take a look at the code, shown in <a href="ch11_02.htm#ch11-79018">Example 11-3</a>.</p><a name="ch11-79018" /><div class="example"><h4 class="objtitle">Example 11-3. shoppe.cgi </h4><a name="INDEX-2265" /><blockquote><pre class="code">#!/usr/bin/perl -wTuse strict;use CGI;use CGIBook::Error;use HTML::Template;BEGIN { $ENV{PATH} = "/bin:/usr/bin"; delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; sub unindent;}use vars qw( $DATA_DIR $SENDMAIL $SALES_EMAIL $MAX_FILES );local $DATA_DIR = "/usr/local/apache/data/tennis";local $SENDMAIL = "/usr/lib/sendmail -t -n";local $SALES_EMAIL = 'sales@email.address.com';local $MAX_FILES = 1000;my $q = new CGI;my $action = $q->param("action") || 'start';my $id = get_id( $q );if ( $action eq "start" ) { start( $q, $id );}elsif ( $action eq "catalog" ) { catalog( $q, $id );}elsif ( $action eq "cart" ) { cart( $q, $id );}elsif ( $action eq "checkout" ) { checkout( $q, $id );}elsif ( $action eq "thanks" ) { thanks( $q, $id );}else { start( $q, $id );}</pre></blockquote></div><p>This script starts like most that we have seen. It calls the<tt class="function">get_id</tt><a name="INDEX-2266" /> function, which we will look at a littlelater; <tt class="function">get_id</tt> returns the session identifier andloads any previously saved session information into the currentCGI.pm object.</p><p>We then branch to an appropriate subroutine depending on the actionrequested. Here are the <a name="INDEX-2267" /> <a name="INDEX-2,268" />subroutines that handle theserequests:</p><blockquote><pre class="code">#/--------------------------------------------------------------------# Page Handling subs# sub start { my( $q, $id ) = @_; print header( $q, "Welcome!" ), $q->p( "Welcome! You've arrived at the world famous Tennis Shoppe! ", "Here, you can order videos of famous tennis matches from ", "the ATP and WTA tour. Well, mate, are you are ready? ", "Click on one of the links below:" ), footer( $q, $id );}sub catalog { my( $q, $id ) = @_; if ( $q->request_method eq "POST" ) { save_state( $q ); } print header( $q, "Video Catalog" ), $q->start_form, $q->table( { -border => 1, -cellspacing => 1, -cellpadding => 4, }, $q->Tr( [ $q->th( { -bgcolor => "#CCCCCC" }, [ "Quantity", "Video", "Price" ] ), $q->td( [ $q->textfield( -name => "* Wimbledon 1980", -size => 2 ), "Wimbledon 1980: John McEnroe vs. Bjorn Borg", '$21.95' ] ), $q->td( [ $q->textfield( -name => "* French Open 1983", -size => 2 ), "French Open 1983: Ivan Lendl vs. John McEnroe", '$19.95' ] ), $q->td( { -colspan => 3, -align => "right", -bgcolor => "#CCCCCC" }, $q->submit( "Update" ) ) ] ), ), $q->hidden( -name => "id", -default => $id, -override => 1 ), $q->hidden( -name => "action", -default => "catalog", -override => 1 ), $q->end_form, footer( $q, $id );}sub cart { my( $q, $id ) = @_; my @items = get_items( $q ); my @item_rows = @items ? map $q->td( $_ ), @items : $q->td( { -colspan => 2 }, "Your cart is empty" ); print header( $q, "Your Shopping Cart" ), $q->table( { -border => 1, -cellspacing => 1, -cellpadding => 4, }, $q->Tr( [ $q->th( { -bgcolor=> "#CCCCCC" }, [ "Video Title", "Quantity" ] ), @item_rows ] ) ), footer( $q, $id );}sub checkout { my( $q, $id ) = @_; print header( $q, "Checkout" ), $q->start_form, $q->table( { -border => 1, -cellspacing => 1, -cellpadding => 4 }, $q->Tr( [ map( $q->td( [ $_, $q->textfield( lc $_ ) ] ), qw( Name Email Address City State Zip ) ), $q->td( { -colspan => 2, -align => "right", }, $q->submit( "Checkout" ) ) ] ), ), $q->hidden( -name => "id", -default => $id, -override => 1 ), $q->hidden( -name => "action", -default => "thanks", -override => 1 ), $q->end_form, footer( $q, $id );}sub thanks { my( $q, $id ) = @_; my @missing; my %customer; my @items = get_items( $q ); unless ( @items ) { save_state( $q ); error( $q, "Please select some items before checking out." ); } foreach ( qw( name email address city state zip ) ) { $customer{$_} = $q->param( $_ ) || push @missing, $_; } if ( @missing ) { my $missing = join ", ", @missing; error( $q, "You left the following required fields blank: $missing" ); } email_sales( \%customer, \@items );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -