📄 ch22.htm
字号:
<TT><FONT FACE="Courier">@keywords = split('+', $ENV{QUERY_STRING});</FONT></TT>
</BLOCKQUOTE>
<P>
Each element of the <TT><FONT FACE="Courier">@keywords</FONT></TT>
array will be assigned an argument. That is, the array will look
like this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">@keywords = ("Its", "deja",
"vu", "all", "over", "again");</FONT></TT>
</BLOCKQUOTE>
<P>
Now you can use these keywords to index into an external database
and return an appropriate response.
<H2><A NAME="WhatAreGETandPOST"><B><FONT SIZE=5 COLOR=#FF0000>What
Are </FONT></B><TT><B><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">GET</FONT></B></TT><B><FONT SIZE=5 COLOR=#FF0000>
and </FONT></B><TT><B><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">POST</FONT></B></TT><B><FONT SIZE=5 COLOR=#FF0000>?</FONT></B></A>
</H2>
<P>
There are two HTTP methods for getting data to a CGI script using
an HTML page: <TT><FONT FACE="Courier">GET</FONT></TT> and <TT><FONT FACE="Courier">POST</FONT></TT>.
The main difference between the two methods of sending data is
in the form of a query string to a CGI script. In the <TT><FONT FACE="Courier">GET</FONT></TT>
method, the query string is appended to the URL of the CGI program
that will be handling the request. Within the CGI script, the
query string will be set to the environment variable <TT><FONT FACE="Courier">QUERY_STRING</FONT></TT>.
In the case of a <TT><FONT FACE="Courier">POST</FONT></TT>, the
browser collects the information from a <TT><FONT FACE="Courier">FORM</FONT></TT>
and presents the data to the CGI script via its standard input.
The main advantage of using a <TT><FONT FACE="Courier">POST</FONT></TT>
request over a <TT><FONT FACE="Courier">GET</FONT></TT> request
is that <TT><FONT FACE="Courier">POST</FONT></TT> requests can
be longer than the maximum allowed length (usually 256) for an
environment variable.
<P>
The <TT><FONT FACE="Courier">GET</FONT></TT> method can be used
without having to encode a <TT><FONT FACE="Courier">FORM</FONT></TT>
because all you have to do is append the query string to the calling
program's URL and send the resulting string to the CGI program.
For example, you could define an anchor tag like this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier"><A HREF="/cgi-bin/summer.pl?name=Kamran%20Husain&y=3">
CGI Sample</A></FONT></TT>
</BLOCKQUOTE>
<P>
This anchor tag will send a <TT><FONT FACE="Courier">GET</FONT></TT>
request to the program <TT><FONT FACE="Courier">summer.pl</FONT></TT>.
The <TT><FONT FACE="Courier">summer.pl</FONT></TT> program in
turn will get the string <TT><FONT FACE="Courier">"name=Kamran%20Husain&y=3"</FONT></TT>
in its environment variable called <TT><FONT FACE="Courier">QUERY_STRING</FONT></TT>.
Note that the question mark (<TT><FONT FACE="Courier">?</FONT></TT>)
in the constructed query string separates the path of CGI script
from the parameters to be passed in the <TT><FONT FACE="Courier">QUERY_STRING</FONT></TT>.
<P>
Note that the <TT><FONT FACE="Courier">%20</FONT></TT> in the
name assignment corresponds to the ASCII representation for a
space, a hex 20. Spaces and special characters are not permitted
in the query string, and so they have to be converted to their
ASCII representations. Here's a Perl statement to convert a given
string into an encoded query string:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$query ~= s/(\W)/sprintf("%%%x",ord($1))/eg;
</FONT></TT>
</BLOCKQUOTE>
<P>
The substitution operator finds all the items that are not words
with the <TT><FONT FACE="Courier">\W</FONT></TT> construct. The
parentheses around the match <TT><FONT FACE="Courier">(\W) </FONT></TT>allow
this match to be referenced in the substituted string. The matched
word is then replaced by its hex equivalent by evaluating the
<TT><FONT FACE="Courier">sprintf</FONT></TT> statement, as specified
by the <TT><FONT FACE="Courier">-e</FONT></TT> flag. The <TT><FONT FACE="Courier">sprintf</FONT></TT>
command simply replaces each matched string <TT><FONT FACE="Courier">$1</FONT></TT>
with a percent sign followed by its ordinal value. The substitution
is done on the entire string by specifying the <TT><FONT FACE="Courier">-g</FONT></TT>
flag.
<P>
So, what's going to be the major difference in the way you are
going to handle the incoming data in your Perl script? When handling
a <TT><FONT FACE="Courier">GET</FONT></TT> request, you are responding
to data in the <TT><FONT FACE="Courier">QUERY_STRING</FONT></TT>
environment variable. When handling the <TT><FONT FACE="Courier">POST</FONT></TT>
request, your Perl script will have to read from <TT><FONT FACE="Courier">STDIN</FONT></TT>,
the default input file handle. In a CGI script, the environment
variable <TT><FONT FACE="Courier">REQUEST_METHOD</FONT></TT> will
be set to either <TT><FONT FACE="Courier">GET</FONT></TT> or <TT><FONT FACE="Courier">POST</FONT></TT>
depending on how the <TT><FONT FACE="Courier">FORM</FONT></TT>
was defined. A <TT><FONT FACE="Courier">FORM</FONT></TT> can be
defined to either method in the <TT><FONT FACE="Courier"><FORM></FONT></TT>
tag with the <TT><FONT FACE="Courier">METHOD</FONT></TT> attribute.
To use the <TT><FONT FACE="Courier">GET</FONT></TT> method for
a CGI script <TT><FONT FACE="Courier">handleIt.pl</FONT></TT>,
you would use the following statement:
<BLOCKQUOTE>
<TT><FONT FACE="Courier"><FORM ACTION="/cgi-bin/handleIt.pl"
METHOD="GET"> </FONT></TT>
</BLOCKQUOTE>
<P>
For using the <TT><FONT FACE="Courier">GET</FONT></TT> method
for the same CGI application and <TT><FONT FACE="Courier">FORM</FONT></TT>,
you would use the following statement:
<BLOCKQUOTE>
<TT><FONT FACE="Courier"><FORM ACTION="/cgi-bin/handleIt.pl"
METHOD="POST"> </FONT></TT>
</BLOCKQUOTE>
<P>
The CGI application you specify in the <TT><FONT FACE="Courier">ACTION</FONT></TT>
attribute of a <TT><FONT FACE="Courier">FORM</FONT></TT> is called
whenever a button of a <TT><FONT FACE="Courier">TYPE</FONT></TT>
attribute <TT><FONT FACE="Courier">"submit"</FONT></TT>
is pressed. To define a <TT><FONT FACE="Courier">"submit"</FONT></TT>
button on a <TT><FONT FACE="Courier">FORM</FONT></TT>, you can
use the following <TT><FONT FACE="Courier"><INPUT></FONT></TT>
tag:
<BLOCKQUOTE>
<TT><FONT FACE="Courier"><INPUT TYPE="submit" VALUE="Just
do it!"></FONT></TT>
</BLOCKQUOTE>
<P>
The line above will create a button on the <TT><FONT FACE="Courier">FORM</FONT></TT>
with a caption set to the string in the <TT><FONT FACE="Courier">VALUE</FONT></TT>
attribute. When this button is pressed, the browser will collect
the information from the fields in the <TT><FONT FACE="Courier">FORM</FONT></TT>
and using the method defined in the <TT><FONT FACE="Courier">METHOD</FONT></TT>
attribute of the <TT><FONT FACE="Courier">FORM</FONT></TT> make
a query string and send it to the CGI application defined in the
<TT><FONT FACE="Courier">ACTION</FONT></TT> attribute.
<P>
Hardwiring a URL with existing question marks and plus signs to
set up the input to a CGI script defeats the purpose of having
a <TT><FONT FACE="Courier">FORM</FONT></TT> in the first place.
This is where the <TT><FONT FACE="Courier">POST</FONT></TT> request
comes in to tell the browser how to make the input string for
you by using the input from a <TT><FONT FACE="Courier">FORM</FONT></TT>.
<H2><A NAME="HandlingHTMLFORMswithGETMethods"><B><FONT SIZE=5 COLOR=#FF0000>Handling
HTML </FONT></B><TT><B><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">FORMs
</FONT></B></TT><B><FONT SIZE=5 COLOR=#FF0000>with </FONT></B><TT><B><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">GET</FONT></B></TT><B><FONT SIZE=5 COLOR=#FF0000>
Methods</FONT></B></A></H2>
<P>
Data collected from an HTML form can also be sent for processing
with the <TT><FONT FACE="Courier">FORM</FONT></TT> keyword using
the <TT><FONT FACE="Courier">GET</FONT></TT> method. See the code
with the HTML page shown in Listing 22.2.
<HR>
<BLOCKQUOTE>
<B>Listing 22.2. Simple </B><TT><B><FONT FACE="Courier">FORM</FONT></B></TT><B>
input.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 <html><head> <title>Welcome.</title>
<BR>
2 </head><BR>
3 <BR>
4 <body><BR>
5 <center><h1>Test A Script</h1></center>
<BR>
6 <hr><BR>
7 <p><BR>
8 <A HREF="http://ikra.com/cgi-bin/test-cgi<BR>
<FONT FACE="ZAPFDINGBATS">Â</FONT>Its+deja+vu+all+over+again" >Click Me</A>
<BR>
9 </p><BR>
10 <p><BR>
11 <FORM<BR>
12 METHOD="GET" ACTION="http://ikra.com/cgi-bin/test-cgi>
<BR>
13 <INPUT TYPE="Submit" VALUE="Just Do It">
<BR>
14 </FORM><BR>
15 <BR>
16 </body></html></FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The rendering of this listing in Netscape is shown in Figure 22.1.
Pressing the Just Do It button returns an argument count of <TT><FONT FACE="Courier">0</FONT></TT>.
<P>
<A HREF="f22-1.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f22-1.gif" ><B>Figure 22.1 : </B><I>A simple form.</I></A>
<P>
Accept some more input from the user to get more information about
the <TT><FONT FACE="Courier">FORM</FONT></TT>. The modified form
is shown in Figure 22.2. Listing 22.3 shows how the text area
was inserted.
<P>
<A HREF="f22-2.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f22-2.gif" ><B>Figure 22.2 : </B><I>Using a simple form with a text area.</I></A>
<P>
The <TT><FONT FACE="Courier"><BR></FONT></TT> tag causes
a line break and forces the button onto the next line. Without
the <TT><FONT FACE="Courier"><BR></FONT></TT> tag, the button
would be on the same line as the text widget (space permitting).
The following tag collects the input for the <TT><FONT FACE="Courier">FORM</FONT></TT>:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">Type something here: <INPUT SIZE=60
NAME="response"></FONT></TT>
</BLOCKQUOTE>
<P>
The length of the string the user can type in is set to 60 characters
wide. The value sent to the shell script from this text widget
is assigned to the keyword <TT><FONT FACE="Courier">response</FONT></TT>.
Let's see how the Perl shell script is called when the button
is pressed.
<HR>
<BLOCKQUOTE>
<B>Listing 22.3. Sample form with text input.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 <html><head><BR>
2 </head><BR>
3 <BR>
4 <body><BR>
5 <center><h1>Test A Script</h1></center>
<BR>
6 <hr><BR>
7 <p><BR>
8 <A HREF="http://ikra.com/cgi-bin/test-cgi<BR>
ÂIts+deja+vu+all+over+again" >Click Me</A>
<BR>
9 </p><BR>
10 <p><BR>
11 <FORM<BR>
12 METHOD="GET" ACTION="http://ikra.com/cgi-bin/test-cgi>
<BR>
13 Type something here: <INPUT SIZE=60 NAME="response">
<BR>
14 <BR><BR>
15 <INPUT TYPE="Submit" VALUE="Just
Do It"><BR>
16 </FORM><BR>
17 <BR>
18 </body></html></FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The output is shown in Figure 22.3. Look closely in the middle
of the figure to see the line:
<P>
<A HREF="f22-3.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f22-3.gif" ><B>Figure 22.3 : </B><I>The output of the request from the text area.</I></A>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">"response=Caution+Cape+does+not+NOT+enable+user+to+fly"</FONT></TT>
</BLOCKQUOTE>
<P>
Look at the value assigned to <TT><FONT FACE="Courier">QUERY_STRING</FONT></TT>.
The "<TT><FONT FACE="Courier">not+NOT</FONT></TT>" is
deliberately done to catch your eye. As you can see, the string
is not easy to read. Look at the title and location of the Netscape
window in Figure 22.3. The value of <TT><FONT FACE="Courier">QUERY_STRING</FONT></TT>
is set to a format that is expected by the CGI script at the
server.
<H2><A NAME="HandlinganHTMLFORMwithPOSTMethods"><B><FONT SIZE=5 COLOR=#FF0000>Handling
an HTML </FONT></B><TT><B><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">FORM</FONT></B></TT><B><FONT SIZE=5 COLOR=#FF0000>
with </FONT></B><TT><B><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">POST</FONT></B></TT><B><FONT SIZE=5 COLOR=#FF0000>
Methods</FONT></B></A></H2>
<P>
Handling the <TT><FONT FACE="Courier">POST</FONT></TT> method
is different than handling the <TT><FONT FACE="Courier">GET</FONT></TT>
method. In the <TT><FONT FACE="Courier">POST</FONT></TT> method,
you use the <TT><FONT FACE="Courier">STDIN</FONT></TT> line as
the source of your input. The length of the string being passed
into the <TT><FONT FACE="Courier">POST</FONT></TT>-handling script
is set in the <TT><FONT FACE="Courier">CONTENT_LENGTH</FONT></TT>
identifier.
<P>
To illustrate the use of <TT><FONT FACE="Courier">CONTENT_LENGTH</FONT></TT>
and <TT><FONT FACE="Courier">POST</FONT></TT> methods, you'll
work with a slightly more complicated input <TT><FONT FACE="Courier">FORM</FONT></TT>.
I'll construct the <TT><FONT FACE="Courier">FORM</FONT></TT> shown
in Figure 22.4. The HTML code for this page is shown in Listing
22.4. The Perl script behind the <TT><FONT FACE="Courier">FORM</FONT></TT>
is shown in Listing 22.5.
<P>
<A HREF="f22-4.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f22-4.gif" ><B>Figure 22.4 : </B><I>Sample credit card application form.</I></A>
<HR>
<BLOCKQUOTE>
<B>Listing 22.4. A sample credit card application form.<BR>
</B>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -