📄 ch22.htm
字号:
<HTML>
<HEAD>
<TITLE>Chapter 22 -- Using HTML FORMs
with Perl CGI Scripts</TITLE>
<META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 22</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Using HTML </FONT></B><TT><B><FONT FACE="Courier" COLOR=#FF0000>FORMs</FONT></B></TT><B><FONT SIZE=5 COLOR=#FF0000> with Perl CGI Scripts</FONT></B></FONT></H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>
<UL>
<LI><A HREF="#InputandOutputwithCGI" >Input and Output with CGI</A>
<LI><A HREF="#WhatAreGETandPOST" >What Are GET and POST?</A>
<LI><A HREF="#HandlingHTMLFORMswithGETMethods" >Handling HTML FORMs with GET Methods</A>
<LI><A HREF="#HandlinganHTMLFORMwithPOSTMethods" >Handling an HTML FORM with POST Methods</A>
<LI><A HREF="#ReturningHTMLPages" >Returning HTML Pages</A>
<LI><A HREF="#UsingtheCollectedData" >Using the Collected Data</A>
<UL>
<LI><A HREF="#ArchivingUserResponses" >Archiving User Responses</A>
<LI><A HREF="#ForwardingUserResponses" >Forwarding User Responses</A>
</UL>
<LI><A HREF="#Summary" >Summary</A>
</UL>
<HR>
<P>
This chapter covers the use of Perl with HTML forms. The topics
include collecting information from an HTML <TT><FONT FACE="Courier">FORM</FONT></TT>
and responding to the requested information. I cover two ways
of querying information from an HTML script: using the <TT><FONT FACE="Courier">GET</FONT></TT>
and <TT><FONT FACE="Courier">POST</FONT></TT> methods. I also
cover how to acquire and then parse data in the Common Gateway
Interface (CGI) script in order to get responses back to the browser.
The information presented in this chapter can easily be expanded
to cover a whole book. There are many different ways of handling
CGI scripts, <TT><FONT FACE="Courier">FORM</FONT></TT>s, and developing
client/server applications, and just as many texts to cover them.
A list of references is provided here if you want more information:
<P>
For more information via printed textbooks, you might want to
consult these titles:
<UL>
<LI><I>Teach Yourself Web Publishing with HTML 3.0 in a Week</I>,
Laura Lemay, Sams.net, 1-57521-064-9, 1996.
<LI><I>HTML & CGI Unleashed</I>, John December and Mark Ginsberg,
Sams.net, 0-672-30745-6, 1995.
<LI><I>Using HTML</I>, Neil Randall, Que, 0-7897-0622-9, 1995.
</UL>
<H2><A NAME="InputandOutputwithCGI"><B><FONT SIZE=5 COLOR=#FF0000>Input
and Output with CGI</FONT></B></A></H2>
<P>
If you have used a Web browser, then you have come across HTML
pages, which allow you to query databases for information. Click
a button and-voilà-you get the latest weather in Colorado.
Just enter a date and destination and you can click a button to
get the travel information you need. What's going on behind the
page? Well, the chances are very high that the information handler
behind the Web page is a Perl script. Perl's power and ease of
handling make it a good choice for setting up support code for
Web pages.
<P>
Before I begin, remember that a CGI script does not have to be
written in Perl, but the ease and convenience of handling strings
makes Perl a very comfortable choice. Because this book is about
Perl, it won't take a wild guess to figure out which language
I cover in this chapter. However, you certainly can write CGI
scripts in any language you like-tcl/Tk, C, C++, or (gasp) even
in Assembler.
<P>
I'll go over a few points about the terminology in this chapter
before I get into the code. An HTML page is picked up and displayed
by a browser on the request of a user using that browser. The
information handling scripts and executables for that page are
handled by the server to which the HTML page's Uniform Resource
Locator (URL) points. The server gets a request for action from
the browser when the user selects the URL. The request is processed
by the server using the CGI, and the results of the CGI executable
are sent back to the browser, which in turn displays them to the
user. When describing the code that handles the requests, it's
easy to use the word <I>user</I> instead of <I>browser</I>. However,
as far as the CGI script on the server is concerned, it's sending
results back to whoever or whatever called it. It's easy to get
the words mixed up, but the intent of both words is to imply the
entity that invoked the CGI script in the first place.
<P>
I introduced you briefly to CGI in <A HREF="ch20.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch20.htm" >Chapter 20</A>,
"An Introduction to Web Pages and CGI." In this chapter,
I cover how the methods for CGI are implemented in HTML forms.
I use the <TT><FONT FACE="Courier">test-cgi.pl</FONT></TT> shell
script (presented earlier) as the basis for setting up shell scripts
for returning data in response to a request. Listing 22.1 presents
a Perl script to echo CGI environment variables.
<HR>
<BLOCKQUOTE>
<B>Listing 22.1. Perl script to echo CGI environment variables.
<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2 #<BR>
3 # The sample script file to echo back ENV<BR>
4 # variables on call from an HTML document.<BR>
5 #<BR>
6 $|=1; #
Flush output immediately.<BR>
7 print "Content-Type: text/plain\r\n";<BR>
8 print "Yet Another CGI/1.0 Test Script\r\n";
<BR>
9 <BR>
10 $count = ($#ARGV + 1);<BR>
11 print "Argument Count: $count";
<BR>
12 foreach $word (@ARGV) {<BR>
13 print
"\n $word";<BR>
14 <BR>
15 print "\n";<BR>
16 #<BR>
17 print "SERVER_SOFTWARE = $ENV{'SERVER_SOFTWARE'}\n";
<BR>
18 print "SERVER_NAME = $ENV{'SERVER_NAME'}\n";<BR>
19 print "GATEWAY_INTERFACE = $ENV{'GATEWAY_INTERFACE'}\n";
<BR>
20 print "SERVER_PROTOCOL = $ENV{'SERVER_PROTOCOL'}\n";
<BR>
21 print "SERVER_PORT = $ENV{'SERVER_PORT'}\n";<BR>
22 print "SERVER_ROOT = $ENV{'SERVER_ROOT'}\n";<BR>
23 print "REQUEST_METHOD = $ENV{'REQUEST_METHOD'}\n";
<BR>
24 print "HTTP_AccEPT = $ENV{'HTTP_AccEPT'}\n";<BR>
25 print "PATH_INFO = $ENV{'PATH_INFO'}\n";<BR>
26 print "PATH = $ENV{'PATH'}\n";<BR>
27 print "PATH_TRANSLATED = $ENV{'PATH_TRANSLATED'}\n";
<BR>
28 print "SCRIPT_NAME = $ENV{'SCRIPT_NAME'}\n";<BR>
29 print "QUERY_STRING = $ENV{'QUERY_STRING'}\n";<BR>
30 print "QUERY_STRING_UNESCAPED = $ENV{'QUERY_STRING_UNESCAPED'}\n";
<BR>
31 print "REMOTE_HOST = $ENV{'REMOTE_HOST'}\n";<BR>
32 print "REMOTE_IDENT = $ENV{'REMOTE_IDENT'}\n";<BR>
33 print "REMOTE_ADDR = $ENV{'REMOTE_ADDR'}\n";<BR>
34 print "REMOTE_USER = $ENV{'REMOTE_USER'}\n";<BR>
35 print "AUTH_TYPE = $ENV{'AUTH_TYPE'}\n";<BR>
36 print "CONTENT_TYPE = $ENV{'CONTENT_TYPE'}\n";<BR>
37 print "CONTENT_LENGTH = $ENV{'CONTENT_LENGTH'}\n";
<BR>
38 print "DOCUMENT_ROOT = $ENV{'DOCUMENT_ROOT'}\n";
<BR>
39 print "DOCUMENT_URI = $ENV{'DOCUMENT_URI'}\n";<BR>
40 print "DOCUMENT_NAME = $ENV{'DOCUMENT_NAME'}\n";
<BR>
41 print "DATE_LOCAL = $ENV{'DATE_LOCAL'}\n";<BR>
42 print "DATE_GMT = $ENV{'DATE_GMT'}\n";<BR>
43 print "LAST_MODIFIED = $ENV{'LAST_MODIFIED'}\n";</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
I'll examine only the Perl scripting features that apply to CGI.
Basically, CGI scripts are executed by the server in response
to a request or action by the URL referenced in the HTML document
being viewed. For example, a URL refers to this document as follows:
<BLOCKQUOTE>
<TT><FONT FACE="Courier"><A<BR>
HREF="http://ikra.com/cgi-bin/test-cgi?Its+de+a+vu+all+over+again"
><BR>
Click me for an echo.<BR>
</A></FONT></TT>
</BLOCKQUOTE>
<P>
The output from this script is as follows. I have truncated it
to save space.
<BLOCKQUOTE>
<TT><FONT FACE="Courier">Yet Another CGI/1.0 Test Script<BR>
<BR>
Argument Count: 6<BR>
Its<BR>
deja<BR>
vu<BR>
all<BR>
over<BR>
again<BR>
SERVER_SOFTWARE = ncSA/1.4.2<BR>
SERVER_NAME = pop.ikra.com<BR>
GATEWAY_INTERFACE = CGI/1.1<BR>
SERVER_PROTOCOL = HTTP/1.0<BR>
SERVER_PORT = 80<BR>
SERVER_ROOT =<BR>
REQUEST_METHOD = GET<BR>
HTTP_AccEPT = */*, image/gif, image/x-xbitmap, image/jpeg<BR>
PATH_INFO =<BR>
PATH = /bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin<BR>
PATH_TRANSLATED =<BR>
SCRIPT_NAME = /cgi-bin/test-cgi<BR>
QUERY_STRING = Its+deja+vu+all+over+again<BR>
QUERY_STRING_UNESCAPED =<BR>
REMOTE_HOST = pop.ikra.com<BR>
REMOTE_IDENT =</FONT></TT>
</BLOCKQUOTE>
<P>
The first action is to reply to the server that text is being
sent back. This is done with the following statement:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">print "Content-Type: text/plain\n\n";</FONT></TT>
</BLOCKQUOTE>
<P>
Examine this <TT><FONT FACE="Courier">test-cgi.pl</FONT></TT>
Perl script and its associated URL in more detail. Notice how
the arguments are being passed into the Perl script. Okay, so
I said <I>Its</I> instead of <I>It's</I>, because I did not want
to escape the single quote (') between the <I>t</I> and <I>s</I>.
<BLOCKQUOTE>
<TT>HREF="http://ikra.com/cgi-bin/test-cgi?Its+de+a+vu+all+over+again"</FONT></TT>
</BLOCKQUOTE>
<P>
The script being referred to in this URL is the <TT><FONT FACE="Courier">test-cgi</FONT></TT>
file on the node <TT><FONT FACE="Courier">ikra.com</FONT></TT>
in the subdirectory <TT><FONT FACE="Courier">cgi-bin</FONT></TT>
of the <TT><FONT FACE="Courier">http</FONT></TT> root directory.
The arguments being passed into this script appear after the question
mark (<TT><FONT FACE="Courier">?</FONT></TT>). Each argument is
separated by a plus sign (<TT><FONT FACE="Courier">+</FONT></TT>).
<P>
The number of arguments, therefore, is six. The string is the
now famous saying that is widely attributed to Yogi Berra, "It's
déjà vu all over again." Now let's see how
the shell script handles this quip.
<P>
The first line to look at is the one in which <TT><FONT FACE="Courier">$|</FONT></TT>
is set to <TT><FONT FACE="Courier">1</FONT></TT>. The <TT><FONT FACE="Courier">$|</FONT></TT>
variable is a special variable in Perl. When the <TT><FONT FACE="Courier">$|</FONT></TT>
variable is set to a non-zero value, Perl forces a flush to the
current output channel. When you are working with CGI applications,
it's important to keep in mind that a quick response will win
you praise. Don't wait for the channel to flush input back to
the caller because the buffering on your output might cause the
client's browser to wait for input for so long that a timeout
is triggered.
<P>
The next line is absolutely necessary and should be printed back
to the browser regardless of how the shell script runs. This line
tells the client what type of data you are sending back. In this
example, plain text is sent back; it's important to let the browser
know about it. This is done by sending back the MIME content identifier:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">print "Content-Type: text/plain\n\n";</FONT></TT>
</BLOCKQUOTE>
<P>
It's nice to know what the returned output is; you can print it
out with this line:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">print "Yet Another CGI/1.0 Test
Script\n\n";</FONT></TT>
</BLOCKQUOTE>
<P>
Next, all the arguments are printed out back to the browser with
the following lines:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$count = ($#ARGV + 1);<BR>
print "Argument Count: $count";<BR>
foreach $word (@ARGV) {<BR>
print "\n $word";<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
The environment variable <TT><FONT FACE="Courier">QUERY_STRING</FONT></TT>
has the arguments to this shell script in the form of <TT><FONT FACE="Courier">Its+deja+vu+all+over+again</FONT></TT>.
In order to parse this string into individual arguments, you have
to split the array where there is a plus sign. This is easily
done with the following line (which is not in Listing 22.1):
<BLOCKQUOTE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -