⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch20.htm

📁 prrl 5 programs codes in the book
💻 HTM
📖 第 1 页 / 共 5 页
字号:

<I>Declare a hash variable to hold the form's input fields.<BR>

Call the </I><TT><I>getFormData()</I></TT><I>

fuNCtion.<BR>

Define the </I><TT><I>getFormData()</I></TT><I>

fuNCtion.<BR>

Declare a local variable to hold the refereNCe to the input field

hash.<BR>

Initialize a buffer.<BR>

If the </I><TT><I>GET</I></TT><I>

method is used, copy the form information into the buffer.<BR>

If the </I><TT><I>POST</I></TT><I>

method is used, read the form information into the buffer.<BR>

Iterate over the array returned by the </I><TT><I>split()</I></TT><I>

fuNCtion.<BR>

Decode both the input field name and value.<BR>

Create an entry in the input field hash variable.<BR>

Define the </I><TT><I>decodeURL()</I></TT><I>

fuNCtion.<BR>

Get the eNCoded string from the parameter array.<BR>

Translate all plus signs into spaces.<BR>

Convert character coded as hexadecimal digits into regular characters.

<BR>

Return the decoded string.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 20.2&nbsp;&nbsp;20LST02.PL-The First Step Is to Get

the Form Information<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

my(%frmFlds);



getFormData(\%frmFlds);



sub getFormData {

    my($hashRef) = shift;

    my($buffer) = &quot;&quot;;



    if ($ENV{'REQUEST_METHOD'} eq 'GET') {

        $buffer = $ENV{'QUERY_STRING'};

    }

    else {

        read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

    }



    foreach (split(/&amp;/, $buffer)) {

        my($key, $value) = split(/=/, $_);

        $key   = decodeURL($key);

        $value = decodeURL($value);

        %{$hashRef}-&gt;{$key} = $value;

    }

}



sub decodeURL {

    $_ = shift;

    tr/+/ /;

    s/%(..)/pack('c', hex($1))/eg;

    return($_);

}

</PRE>

</BLOCKQUOTE>

<HR>

<P>

The <TT>getFormData()</TT> fuNCtion

could be considered complete at this point. It correctly reads

from both the <TT>GET</TT> and <TT>POST</TT>

transmission methods, decodes the information, and places the

input fields into a hash variable for easy access.

<P>

There are some additional considerations of which you need to

be aware. If you simply display the information that a user entered,

there are some risks involved that you may not be aware of. Let's

take a simple example. What if the user enters <TT>&lt;B&gt;Rolf&lt;/B&gt;</TT>

in the <TT>name</TT> field and you

subsequently displayed that field's value? Yep, you guessed it,

<TT>Rolf</TT> would be displayed in

bold! For simple formatting HTML tags this is not a problem, and

may even be a feature. However, if the user entered an SSI tag,

he or she may be able to take advantage of a security hole-remember

the <TT>&lt;!--#exec --&gt;</TT> tag?

<P>

You can thwart would-be hackers by converting every instaNCe of

<TT>&lt;</TT> to <TT>&amp;lt;</TT>

and of <TT>&gt;</TT> to <TT>&amp;gt;</TT>.

The HTML standard allows for certain characters to be displayed

using symbolic codes. This allows you to display a <TT>&lt;</TT>

character without the web browser thinking that a new HTML tag

is starting.

<P>

If you'd like to give users the ability to retain the character

formatting HTML tags, you can test for each tag that you want

to allow. When an allowed tag is found, reconvert it back to using

normal <TT>&lt;</TT> and <TT>&gt;</TT>

tags.

<P>

You might want to check for users entering a series of <TT>&lt;P&gt;</TT>

tags in the hopes of generating pages and pages of blank lines.

Also, you might want to convert pressing the enter key into spaces

so that the line endings that the user entered are ignored and

the text will wrap normally when displayed by a web browser. One

small refinement of eliminating the line endings could be to convert

two consecutive newlines into a paragraph (<TT>&lt;P&gt;</TT>)

tag.

<P>

When you put all of these new features together, you wind up with

a <TT>getFormData()</TT> fuNCtion

that looks like Listing 20.3.

<P>

<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>

<BLOCKQUOTE>

<I>Declare a hash variable to hold the form's input fields.<BR>

Call the </I><TT><I>getFormData()</I></TT><I>

fuNCtion.<BR>

Define the </I><TT><I>getFormData()</I></TT><I>

fuNCtion.<BR>

Declare a local variable to hold the refereNCe to the input field

hash.<BR>

Initialize a buffer.<BR>

If the </I><TT><I>GET</I></TT><I>

method is used, copy the form information into the buffer.<BR>

If the </I><TT><I>POST</I></TT><I>

method is used, read the form information into the buffer.<BR>

Iterate over the array returned by the </I><TT><I>split()</I></TT><I>

fuNCtion.<BR>

Decode both the input field name and value.<BR>

Compress multiple </I><TT><I>&lt;P&gt;</I></TT><I>

tags into one.<BR>

Convert </I><TT><I>&lt;</I></TT><I>

into </I><TT><I>&amp;lt;</I></TT><I>

and </I><TT><I>&gt;</I></TT><I> into

</I><TT><I>&amp;gt;</I></TT><I> stopping

HTML tags from interpretation.<BR>

Turn back on the bold and italic HTML tags.<BR>

Remove unneded carriage returns.<BR>

Convert two newlines into a HTML paragraph tag.<BR>

Convert single newlines into spaces.<BR>

Create an entry in the input field hash variable.<BR>

Define the </I><TT><I>decodeURL()</I></TT><I>

fuNCtion.<BR>

Get the eNCoded string from the parameter array.<BR>

Translate all plus signs into spaces.<BR>

Convert character coded as hexadecimal digits into regular characters.

<BR>

Return the decoded string.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 20.3&nbsp;&nbsp;20LST03.PL-The First Step Is to Get

the Form Information<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

my(%frmFlds);



getFormData(\%frmFlds);



sub getFormData {

    my($hashRef) = shift;

 my($buffer) = &quot;&quot;;



    if ($ENV{'REQUEST_METHOD'} eq 'GET') {

        $buffer = $ENV{'QUERY_STRING'};

    }

    else {

        read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

    }



    foreach (split(/&amp;/, $buffer)) {

        my($key, $value) = split(/=/, $_);

        $key   = decodeURL($key);

        $value = decodeURL($value);



        $value =~ s/(&lt;P&gt;\s*)+/&lt;P&gt;/g;   # compress multiple &lt;P&gt; tags.

        $value =~ s/&lt;/&amp;lt;/g;           # turn off all HTML tags.

        $value =~ s/&gt;/&amp;gt;/g;

        $value =~ s/&amp;lt;b&amp;gt;/&lt;b&gt;/ig;   # turn on the bold tag.

        $value =~ s!&amp;lt;/b&amp;gt;!&lt;/b&gt;!ig;

        $value =~ s/&amp;lt;i&amp;gt;/&lt;b&gt;/ig;   # turn on the italic tag.

        $value =~ s!&amp;lt;/i&amp;gt;!&lt;/b&gt;!ig;

        $value =~ s!\cM!!g;            # Remove unneeded carriage re

        $value =~ s!\n\n!&lt;P&gt;!g;        # Convert 2 newlines into para

        $value =~ s!\n! !g;            # Convert newline into spaces.

        %{$hashRef}-&gt;{$key} = $value;

    }

}



sub decodeURL {

    $_ = shift;

    tr/+/ /;

    s/%(..)/pack('c', hex($1))/eg;

    return($_);

}

</PRE>

</BLOCKQUOTE>

<HR>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD><B>Caution</B></TD></TR>

<TR><TD>

<BLOCKQUOTE>

Tracking security problems seems like a never-ending task but it is very important, especially if you are responsible for a web server. As complicated as the <TT>getFormData()</TT> fuNCtion is, it is still not complete. The <TT>&lt;TEXTAREA&gt;</TT> tag 
lets users enter an unlimited amount of information. What would happen to your web server if someone used the cut and paste ability in Windows 95 to insert four or five megabytes into your form? Perhaps the <TT>getFormData()</TT> fuNCtion should have some 
type of limitation that any individual field should only be 1,024 bytes in length?

</BLOCKQUOTE>



</TD></TR>

</TABLE>

</CENTER>

<P>

<H2><A NAME="FillinginaFormandMailingtheInformation"><FONT SIZE=5 COLOR=#FF0000>

Filling in a Form and Mailing the Information</FONT></A></H2>

<P>

You can have a form's information automatically mailed to an email

address by using the <TT>mailto:</TT>

notation in the <TT>ACTION</TT> modifier

of the <TT>&lt;FORM&gt;</TT> tag.

For example,

<BLOCKQUOTE>

<PRE>

&lt;FORM METHOD=get ACTION=mailto:medined@planet.net&gt;

</PRE>

</BLOCKQUOTE>

<P>

When the form's submit button is clicked, the form's information

will be mailed to the email address specified in the <TT>&lt;FORM&gt;</TT>

tag. The information will be URL eNCoded and all on one line.

This means you can't read the information until it has been processed.

<P>

It is generally a bad idea to email form information because of

the URL eNCoding that is done. It is better to save the information

to a data file so that you can easily read and analyze it later.

Sending notifications by email is a good idea. For example, you

could tell an email reader that a certain form has been completed

and that the log file should be checked. If you want to send email

from a CGI script, you can use the sample program from Listing

18.2 in <A HREF="ch18.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch18.htm" >Chapter 18</A>, &quot;Using Internet Protocols.&quot;

<P>

Before sending any form information, ensure that it has been decoded.

If you are using one of the CGI modules or the decoding fuNCtions

from <A HREF="ch19.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch19.htm" >Chapter 19</A>, &quot;What Is CGI?,&quot; then you don't have

to worry about this requirement. Otherwise, please reread the

section called &quot;URL ENCoding&quot; in <A HREF="ch19.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch19.htm" >Chapter 19</A>.

<P>

Make sure to use a <TT>Reply-To</TT>

field in the body of your email message because you won't know

which login name the CGI program will be running under. INCluding

the <TT>Reply-To</TT> field will ensure

that the reader of the message can easily respond to the email

message if needed.

<H2><A NAME="DebuggingFormProcessingCGIScripts"><FONT SIZE=5 COLOR=#FF0000>

Debugging Form Processing CGI Scripts</FONT></A></H2>

<P>

CGI programs get their information from three sources: the URL

that invokes them, environment variables, and from the <TT>STDIN</TT>

filehandle. Most of the time, this information comes from the

web server that invokes the CGI script. However, you can manually

recreate the script's normal environment. This lets you debug

a CGI program from the operating system's command line which should

save you time.

<P>

The first thing to look at is how to set environment variables.

The method used depends on your operating system. Table 20.2 shows

you how to set environment variables for a variety of operating

systems.<BR>

<P>

<CENTER><B>Table 20.2&nbsp;&nbsp;How to Set Environment Variables

by Hand</B></CENTER>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD WIDTH=164><I>Operating System</I></TD><TD WIDTH=349><I>Command Or UNIX Command Shells</I>

</TD></TR>

<TR><TD WIDTH=164>csh</TD><TD WIDTH=349><TT>setenv HTTP_USER_AGENT &quot;Mozilla&quot;</TT>

</TD></TR>

<TR><TD WIDTH=164>ksh or bash</TD><TD WIDTH=349><TT>export HTTP_USER_AGENT = &quot;Mozilla&quot;</TT>

</TD></TR>

<TR><TD WIDTH=164>Win95, WinNT, OS/2</TD><TD WIDTH=349><TT>set HTTP_USER_AGENT = Mozilla</TT>

</TD></TR>

</TABLE>

</CENTER>

<P>

<P>

In order to recreate the environmental variables that a server

sets, you need to initialize at least the following environmental

variables:

<UL>

<LI>CONTENT_LENGTH-If you are using the <TT>POST</TT>

method of processing information, set this variable to the length

of the input. Finding the input length is easier than it sounds.

SiNCe you'll be creating a file to hold the test form information,

you only need to find that file's size.

<LI>REQUEST_METHOD-You should set this to either <TT>GET</TT>

or <TT>POST</TT>.

<LI>QUERY_STRING-You should value this variable, if you are using

the <TT>GET</TT> method or if your

script needs information passed to it via its URL and the extra

information should follow a question mark (<TT>?</TT>).

<LI>PATH_INFO-If your script needs information passed to it via

its URL and the extra information should follow a slash (<TT>/)</TT>,

then value this variable with the extra information.

</UL>

<P>

You also need to initialize any other variables that your program

needs. Rather than retyping the <TT>set</TT>

commands each time you want to test your CGI program, create a

shell or batch file.

<P>

The next step is to create a text file that will be substituted

for STDIN when the CGI program is run. You only need to create

this text file if you are using the <TT>GET</TT>

method. The text file can be called anything you'd like and should

contain just one line-the line of form information. For example:

<BLOCKQUOTE>

<PRE>

name=Rolf D'Barno&amp;age=34

</PRE>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -