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

📄 ch12.htm

📁 CGI programming is the hottest stuff to look out for in this book
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<BLOCKQUOTE>
within.</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<P>
Seriously, enabling the .map Magic MIME type allows you to write
your imagemap HTML statements in a slightly altered format:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">&lt;A HREF=&quot;map_URL&quot;&gt;&lt;IMG
SRC=&quot;image.gif&quot; ISMAP&gt;&lt;/A&gt;</FONT></TT>
</BLOCKQUOTE>
<P>
What ncSA has essentially done is incorporate their imagemap.c
source code into the httpd.c source code, making the standard
imagemap handler part of the standard Web server! Rather than
unloading imagemap handling onto an external imagemap handling
program that references an auxiliary map file, the server references
that map file directly and deals with it internally. I have composed
a working (if simple) example of this in action:
<BLOCKQUOTE>
<TT><FONT FACE="Courier"><A HREF="http://www.anadas.com/cgiunleashed/imagemaps/magic.html">http://www.anadas.com/cgiunleashed/imagemaps/magic.html</A>&lt;HTML&gt;
<BR>
&lt;HEAD&gt;&lt;TITLE&gt;Example using the .map Magic MIME type&lt;/TITLE&gt;&lt;/HEAD&gt;
<BR>
&lt;BODY&gt;<BR>
&lt;P&gt;Click somewhere in the image below:&lt;BR&gt;&lt;BR&gt;
<BR>
&lt;A HREF=&quot;exe/magic.map&quot;&gt;&lt;IMG SRC=&quot;images/magic.gif&quot;
ISMAP&gt;&lt;/A&gt;<BR>
&lt;/BODY&gt;&lt;/HTML&gt;</FONT></TT>
</BLOCKQUOTE>
<P>
The ncSA/1.5 server is instructed by this HTML to reference the
following map file:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">default /cgiunleashed/imagemaps/elsewhere.html
<BR>
<BR>
# inside the black circle<BR>
circle /cgiunleashed/imagemaps/circle.html 70,72 70,122</FONT></TT>
</BLOCKQUOTE>
<H2><A NAME="TakeaWalkontheServerSideDevelopin"><FONT SIZE=5 COLOR=#FF0000>Take
a Walk on the Server-Side-Developing Imagemap Code</FONT></A>
</H2>
<P>
So far in this chapter, I've talked the talk. Now, I think it's
time to walk the walk. For your viewing pleasure, I've written
an imagemap handler that is functionally similar to the standard
ncSA code but includes a fair number of differences, as well.
Being the creative guy that I am, I have decided to call my masterpiece
im.cgi.
<P>
im.cgi is written in Perl and developed for a UNIX platform. By
now I'm sure you've all heard that Perl is the best language for
CGI development. I would call this statement a justified simplification.
Perl is an excellent language for writing programs that handle
strings and files and that are reasonably small and uncomplicated.
This description would fit the vast majority of CGI programs.
I've written CGI programs in C and C++ when it was appropriate
to do so, but for CGI programs, I always go to Perl first.
<P>
I'm not going to spend any time in this chapter discussing Perl
as a language. Information about it is very available on the Internet
and in bookstores-that's how I learned it, after all. im.cgi is
fairly well documented, and you should be able to get the meaning
of most Perl commands and structures from the context in which
they are used.
<P>
im.cgi gets the ISMAP-produced x,y pair through the <TT><FONT FACE="Courier">QUERY_STRING</FONT></TT>
environment variable. This coordinate pair is compared against
geometries found in an .imap file; .imap files are not structured
in exactly the same way as an .map file, though. Valid methods
in an .imap file are rect, ellipse, point, and default. The area
that a rect or ellipse delimits is described in a new format I
have outlined in a logical .imap example later in the chapter.
For the sake of simplicity, I have eliminated the poly method.
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Dealing with polygons can be horrendously complicated both in computer programming and in mathematics (geometry and topology). A general polygon can be convex or concave. This makes it difficult for a program to determine whether a point is inside or 
outside of the polygon region. Even worse, a polygon may be connected multiply (see Figure 12.4). Then, it's tough to even know which side of the polygon is on the inside or outside! In any case, a reference point needs to be chosen to allow for a 
determination of on which side of the polygon an arbitrary point may lie.</BLOCKQUOTE>
<BLOCKQUOTE>
Complex geometry is the square root of all evil.</BLOCKQUOTE>
<BLOCKQUOTE>
Sorry.</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<P>
<A HREF="f12-4.gif" ><B>Figure 12.4:</B> <I>Problem polygons</I></A>.
<P>
Here are examples of a concave polygon and a multiply connected
polygon. Shapes that fall under these categories are difficult
to work with in computer programs. To help make the job easier,
assumptions are usually made that simplify (though possibly misrepresent)
the situation. In addition to (slightly) changing the allowable
methods, I've changed the structure of each line. URLs follow
rather than precede the geometry-specifying information. Also,
im.cgi doesn't handle relative URLs-they have to be specified
in full, including the <TT><FONT FACE="Courier">http://</FONT></TT>
at the front. Blank lines are skipped, and lines starting with
<TT><FONT FACE="Courier">#</FONT></TT> are treated as comments
and are ignored. The first line of an .imap file contains the
alias meant to be compared against the <TT><FONT FACE="Courier">PATH_INFO</FONT></TT>
environment variable. Only uppercase and lowercase alphabetic
characters are valid for this alias name; im.cgi doesn't support
direct references to .imap files as imagemap.cgi does for .map
files-<TT><FONT FACE="Courier">pathinfo</FONT></TT> aliases must
be used. As a result, .imap files must be in the same directory
as im.cgi. If a mouse-click is found to be contained within a
rect or ellipse, the program will &quot;short-circuit&quot; and
immediately bring the user to the URL specified by that shape.
The consequence of this is that if rects or ellipses overlap,
the shape described first in the .imap file takes precedence.
It is possible to specify a shape that lies outside the boundaries
of the actual image file the .imap file relates to-this could
be useful if you want to have a clickable semicircle at the edge
of an image. The point method works the same as it did in imagemap.cgi.
If a file has any point methods specified, any default methods
are ignored. There are no restrictions on where methods are placed
within a file apart from that the first line is reserved for the
alias name.
<P>
This is all very similar to the structure of a .map file. I have
added one &quot;twist&quot; to it all, though. rect, ellipse,
and default methods may be specified by more than one URL. If
more than one URL is specified for any one of these methods, im.cgi
will choose one randomly. Also, there can be more than one default
line-a convenience to allow for the input of many alternative
default URLs to be randomly chosen from, without putting many
URLs on one line. To be honest, I can't think of a really good
application for this. However, I wanted to demonstrate that things
that are completely outside the capabilities of imagemap.cgi are
possible when you write your own imagemap handler.
<P>
All these principles are demonstrated by the following logical
.imap file:
<BLOCKQUOTE>
<TT><FONT FACE="Courier"># mapfilealias<BR>
# The above is the path info alias for this .imap file.<BR>
<BR>
rect upperleftx,upperlefty xsize ysize URL1 ... URLn<BR>
ellipse centerx,centery xsemiaxis ysemiaxis URL1 ... URLn<BR>
<BR>
point x1,y1 URL<BR>
...<BR>
point xn,yn URL<BR>
<BR>
default URL ... URL<BR>
...<BR>
default URL ... URL<BR>
</FONT></TT>
</BLOCKQUOTE>
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
An ellipse is a useful and fascinating shape and fairly easy to work with, too. I'm not sure why the standard imagemap code uses circles instead. After all, a circle is just an ellipse with equal x and y radii. Figure 12.5 is a diagram showing you the 
geometry of an ellipse and the algebra associated with it.</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<P>
<A HREF="f12-5.gif" ><B>Figure 12.5:</B> <I>Anatomy of an ellipse.</I></A>
<P>
You can see an example of my im.cgi program (shown in Listing
12.1) at work at the following URL:
<BLOCKQUOTE>
<TT><FONT FACE="Courier"><A HREF="http://www.anadas.com/cgiunleashed/imagemaps/immap.html"><A HREF="http://www.anadas.com/cgiunleashed/imagemaps/immap.html">http://www.anadas.com/cgiunleashed/imagemaps/immap.html</A></A></FONT></TT>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 12.1. im.cgi program-an alternative imagemap handler.
<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#!/usr/bin/perl<BR>
# the above line may need to be altered depending on where Perl
is<BR>
# stored on your system<BR>
<BR>
#<BR>
# This program written by Richard Dice of Anadas Software Development
<BR>
# as part of the Sams Net &quot;CGI Programming Unleashed&quot;
book.&nbsp;&nbsp;The author<BR>
# intends this code to be used for instructional purposes and
not for<BR>
# resale or commercial gain.<BR>
#<BR>
# Any questions or comments regarding this program are welcome.&nbsp;&nbsp;You
<BR>
# may contact the author by Internet email: rdice@anadas.com<BR>
#<BR>
<BR>
#<BR>
# initialize some variables, partly because it's an old habit,
partly<BR>
# so that they aren't treated as variables localized to loops
<BR>
#<BR>
$imap = '';<BR>
$c = 0;<BR>
$found = 0;<BR>
$this_rect = 0;<BR>
$this_ellipse = 0;<BR>
<BR>
# seed the random number generator for the 'rand' command<BR>
srand;<BR>
<BR>
# Get GET co-ordinate information and place in x and y variables
<BR>
($x,$y) = split(/,/,$ENV{QUERY_STRING});<BR>
<BR>
#<BR>
# Get PATH_INFO information -- this will be used to determine
which .imap file<BR>
# to use.&nbsp;&nbsp;Any character which is not in the range a-z
or A-Z will be removed.<BR>
# This is like the imagemap.conf file, but forces each .imap file
to be<BR>
# responsible for its own alias.<BR>
#<BR>
($filematch = $ENV{PATH_INFO}) =~ tr/a-zA-Z//cd;<BR>
<BR>
#<BR>
# determines the names of all .imap files in the directory which
houses im.cgi<BR>
# and uses the UNIX head command to look at the first lines of
each of them<BR>
# until a match with $filematch (derived from PATH_INFO) is made.
<BR>
#<BR>
@imapfiles = &lt;*.imap&gt;;<BR>
foreach ( @imapfiles ) {<BR>
&nbsp;&nbsp;&nbsp;$firstline = 'head -1 $_';<BR>
&nbsp;&nbsp;&nbsp;if ( $firstline =~ /$filematch/ ) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$found = 1;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$imap = $_;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;last;<BR>
&nbsp;&nbsp;&nbsp;}<BR>
}<BR>
@imapfiles = ();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#
this array is unneeded, so free up memory<BR>
&amp;not_there unless $found; # if no matching .imap file, abort
with error msg.<BR>
<BR>
open(IMAP,$imap);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#
now, I start parsing the desired .imap file<BR>
while ( &lt;IMAP&gt; ) {<BR>
&nbsp;&nbsp;&nbsp;next if ($_ eq &quot;\n&quot;); # blank lines
are ignored<BR>
&nbsp;&nbsp;&nbsp;next if ($_ =~ /^\#/ ); # lines starting with
# are also skipped<BR>
<BR>
#<BR>
# the following line creates an array called @line based on the
contents of<BR>
# the current line being read in from the .imap file.&nbsp;&nbsp;Whitespace
is used as<BR>
# array element delimiters.&nbsp;&nbsp;Isn't Perl grand? :-)<BR>
#<BR>
&nbsp;&nbsp;&nbsp;@line = split;<BR>
<BR>
#<BR>
# break the .imap file-reading loop if the current line being

⌨️ 快捷键说明

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