📄 ch19.htm
字号:
print("</BODY>");
print("</HTML>");
sub setCookie {
my($name, $val, $exp, $path, $dom, $secure) = @_;
print("Set-Cookie: ");
print("$name=$val, expires=$exp, path=$path, domain=$dom");
print(", $secure") if defined($secure);
print("\n");
}
sub getCookies {
my(%cookies);
foreach (split (/; /,$ENV{'HTTP_COOKIE'})){
my($key) = split(/=/, $_);
$cookies{$key} = substr($_, index($_, "=")+1);
}
return(%cookies);
}
</PRE>
</BLOCKQUOTE>
<HR>
<P>
This program shows that the Web server stores a copy of any cookies
that you set into the <TT>HTTP_COOKIE</TT>
environment variable. It only performs one level of parsing. In
order to create a really useful <TT>getCookies()</TT>
fuNCtion, you need to split the cookie on the comma character
and then again on the equals character.
<H3><A NAME="CanaVisitorsBrowserSupportCookies">
Can a Visitor's Browser Support Cookies?</A></H3>
<P>
One difficulty that you may have in using cookies is that not
every browser can support them. If you are using cookies, you
need a user-friendly way of telling a visitor that the feature
he or she is trying to use is not available to him or her.
<P>
Listing 19.5 contains a script that shows you a nice way of automatically
determining if a visitor's Web browser supports cookies. The CGI
program will set a cookie and then redirect the visitor's Web
browser back to itself with some additional path information.
When the script (during its second invocation) sees the extra
path information, it checks for the previously created cookie.
If it exists, the visitor's browser has passed the test. Otherwise,
the visitor's browser does not support cookies.
<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>Turn on the warning option.<BR>
<I>Turn on the strict pragma.<BR>
<I>If there is no query information, then set a cookie and reload
the script.<BR>
<I>Otherwise, see if the cookie set before the reload exits.<BR>
<I>If the cookie exists, the browser supports cookies.<BR>
<I>If the cookie does not exist, the browser does not support
cookies.</I></I></I></I></I></I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 19.5 19LST05.PL-How to Tell Whether the
Visitor's Browser Supports Cookies<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
#!/usr/bin/perl -w
use strict;
if ($ENV{'QUERY_STRING'} ne 'TESTING') {
print "HTTP/1.0 302 Moved Temporarily\n";
print "Set-Cookie: Cookie=Test\n";
print "Location: $ENV{'SCRIPT_NAME'}?TESTING\n\n";
}
else {
if ($ENV{'HTTP_COOKIE'} =~ /Cookie=Test/) {
print("Content-type: text/html\n\n");
print("<HTML>");
print("<HEAD><TITLE>$ENV{'HTTP_USER_AGENT'} supports Cookies
</TITLE></HEAD>");
print("<BODY>");
print("Your browser, $ENV{'HTTP_USER_AGENT'}, supports the
Netscape HTTP ");
print("Cookie Specification.");
print("</BODY></HTML>");
}
else {
print("Content-type: text/html\n\n");
print("<HTML>");
print("<HEAD><TITLE>$ENV{'HTTP_USER_AGENT'} doesn't support
Cookies</TITLE></HEAD>");
print("<BODY>");
print("Your browser, $ENV{'HTTP_USER_AGENT'}, doesn't appear to
support cookies.");
print("Cookie Specification.");
print("</BODY></HTML>");
}
}
</PRE>
</BLOCKQUOTE>
<HR>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TDz>
<BLOCKQUOTE>
You can find more information about cookies at these Web sites:</BLOCKQUOTE>
<BLOCKQUOTE>
<TT>http://home.netscape.com/newsref/std/cookie_spec.html<BR>
http://www.netscapeworld.com/netscapeworld/nw-07-1996/nw-07-cookies.html<BR>
http://www.emf.net/~mal/cookiesinfo.html<BR>
http://ds.internic.net/internet-drafts/draft-ietf-http-state-mgmt-03.txt<BR>
http://www.illuminatus.com/cookie/<BR>
http://www.jasmin.com/cook0696.html<BR>
http://www.bravado.net/rodgers/InterNetNews.html</TT>
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<H2><A NAME="DebuggingCGIPrograms"><FONT SIZE=5 COLOR=#FF0000>
Debugging CGI Programs</FONT></A></H2>
<P>
One of the main reasons to use CGI programs is to generate HTML
documents. When something goes wrong, the common error message
will be 500 Server Error. This message can be caused by several
things. For example, the #! comment at the top of your script
could be invalid, the first line of output was an invalid HTTP
header, there might not be a blank line after the HTTP header,
or you could simply have a syntax error.
<H3><A NAME="SendingOutputtotheServersLogFile">
Sending Output to the Server's Log File</A></H3>
<P>
When your CGI program starts, the <TT>STDERR
</TT>file handle is connected to the server's error log.
You can use <TT>STDERR </TT>to save
status messages that you don't want the user to see. The advantage
of using <TT>STDERR </TT>is that you
don't need to open or close a file. In addition, you'll always
know where the messages are. This is important if you're working
on a team.
<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>Send the HTTP header indicating a plain text document.<BR>
Send a line of text.<BR>
Call the </I><TT><I>logError()</I></TT><I>
fuNCtion to send a message to the server's log file.<BR>
Send a line of text.<BR>
Define the </I><TT><I>logError()</I></TT><I>
fuNCtion<BR>
Declare a local variable to hold the message.<BR>
Print the message to </I><TT><I>STDERR </I></TT><I>with
a timestamp.<BR>
Define the </I><TT><I>timeStamp()</I></TT><I>
fuNCtion.<BR>
Declare some local variables to hold the current date and time.
<BR>
Call the </I><TT><I>zeroFill()</I></TT><I>
fuNCtion to format the numbers.<BR>
Return a formatted string holding the current date and time.<BR>
Define the </I><TT><I>zeroFill()</I></TT><I>
fuNCtion-turns "1" into "01."<BR>
Declare a local variable to hold the number to be filled.<BR>
Declare a local variable to hold the string length that is needed.
<BR>
Find differeNCe between current string length and needed length.
<BR>
If the string is big enough (like "12"), then return
it.<BR>
If the string is too big, prefix it with some zeroes.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 19.6 19LST06.PL-Sending Messages to the
Server's Error Log<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
print("Content-type: text/plain\n\n");
print("This is line one.\n");
logError("GOOD Status\n");
logError("BAD Status\n");
print("This is line two.\n");
sub logError {
my($msg) = shift;
print STDERR (timeStamp(), " $msg");
}
sub timeStamp {
my($sec, $min, $hour, $mday, $mon, $year) = (localtime(time))[0..5];
$mon = zeroFill($mon, 2);
$hour = zeroFill($hour, 2);
$min = zeroFill($min, 2);
$sec = zeroFill($sec, 2);
return("$mon/$mday/$year, $hour:$min:sec");
}
sub zeroFill {
my($temp) = shift;
my($len) = shift;
my($diff) = $len - length($temp);
return($temp) if $diff <= 0;
return(('0' x $diff) . $temp);
}
</PRE>
</BLOCKQUOTE>
<HR>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Caution</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
According to the CGI specifications, the <TT>STDERR</TT> file handle should be connected to the server's error log. However, I found that this was not true when using Windows 95 and O'Reilly's Website server software. There may be other combinations of
operating systems and server software that also fail to connect <TT>STDERR</TT> to the error log.
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<H3><A NAME="SendingSTDERRtotheWebBrowser">
Sending STDERR to the Web Browser</A></H3>
<P>
If you want your users to see the error messages your script generates,
use the <TT>open()</TT> fuNCtion to
redirect <TT>STDERR</TT> to <TT>STDOUT</TT>
like this:
<BLOCKQUOTE>
<PRE>
open(STDERR, ">&STDOUT");
</PRE>
</BLOCKQUOTE>
<P>
After that statement is executed, the output of all print statements
that use the STDERR file handle will be displayed in the Web browser
window.
<P>
You need to be a little careful when using this ability. Your
normal error messages will not have the HTML tags required to
make them display properly.
<H3><A NAME="CGITap">
CGITap</A></H3>
<P>
CGITap (<B>http://scendtek.com/cgitap/</B>) is a CGI debugging
aid that can help pinpoint the problem in a troubling CGI application.
CGITap installs in the <TT>cgi-bin</TT>
directory and runs any CGI programs in "tap mode." Tap
mode runs the CGI program as normal; however, the output contains
additional diagnostic and environment information. This information
can greatly speed up the process of debugging your CGI scripts.
<P>
CGITap may be installed in any CGI enabled directory and requires
perl4.036 or later. You can install CGITap by following these
steps:
<OL>
<LI>Download the CGITap script from the <B>http://scendtek.com/cgitap/</B>
Web page.
<LI>Install CGITap in a CGI enabled directory-typically named
cgi-bin.
<LI>As with any Perl script, be sure the first line of CGITap
contains the correct path to your system's Perl interpreter. You
should be familiar with the location. If not, try typing <B>which
perl</B> on the UNIX command line.
<LI>Check the file permissions to ensure that CGITap is executable.CGITap
has two methods of debugging. The first is adequate for simple
CGI applications that do not use HTML forms for input. The second
method is used for CGI programs that process HTML form information.
</OL>
<P>
For simple CGIs, add <TT>cgitap</TT>
to the URL. For example, normally a CGI program that just prints
the date is called like this:
<P>
<TT>http://localhost/cgi-bin/date</TT>
<P>
That CGI program might display the following in the browser's
window:
<BLOCKQUOTE>
<PRE>
Sun Aug 18 16:07:37 EST 1996
</PRE>
</BLOCKQUOTE>
<P>
In order to use CGITap for debugging, use a similar URL but with
<TT>cgitap</TT> inserted.
<BLOCKQUOTE>
<PRE>
http://localhost/cgi-bin/cgitap/date
</PRE>
</BLOCKQUOTE>
<P>
CGITap will extract your CGI program's name, display the CGI environment
to the browser, perform some checks on the program, then execute
the program and return the actual results (both in HTML source
and the actual document).
<P>
CGI programs that process HTML forms will be discussed in Chapter
20, "Form Processing," but while I'm talking about CGITap,
let me also mention how to use CGITap with HTML forms. A slightly
more complicated method must be used for debugging complex CGI
scripts that require form
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -