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

📄 ch07_03.htm

📁 用perl编写CGI的好书。本书从解释CGI和底层HTTP协议如何工作开始
💻 HTM
📖 第 1 页 / 共 2 页
字号:
            if ( data.artist[i]  == selectedValue( form.artistList  ) &amp;&amp;                 data.concert[i] == selectedValue( form.concertList ) &amp;&amp;                 data.song[i]    == selectedValue( form.songList    ) ) {                idx = i;                break;            }        }                form.artist.value   = idx &lt; 0 ? data.artist[idx]   : "";        form.concert.value  = idx &lt; 0 ? data.concert[idx]  : "";        form.song.value     = idx &lt; 0 ? data.song[idx]     : "";        form.venue.value    = idx &lt; 0 ? data.venue[idx]    : "";        form.date.value     = idx &lt; 0 ? data.date[idx]     : "";        form.duration.value = idx &lt; 0 ? data.duration[idx] : "";        form.size.value     = idx &lt; 0 ? data.size[idx]     : "";        form.filename.value = idx &lt; 0 ? data.filename[idx] : "";    }            function getSong(  ) {        var form = document.mbrowser;        if ( form.filename.value == "" ) {            alert( "Please select an artist, concert, and song to download." );            return;        }        open( archive_url + form.filename.value, "song" );    }            function listMsg ( list, msg ) {        list.options.length = 0;        list.options[0] = new Option(  );        list.options[0].text  = msg;        list.options[0].value = "--";    }            function selectedValue( list ) {        return list.options[list.selectedIndex].value;    }      // --&gt;  &lt;/SCRIPT&gt;&lt;/HEAD&gt;&lt;BODY BGCOLOR="#FFFFFF" onLoad="showArtists(  )"&gt;  &lt;TABLE WIDTH="100%" BGCOLOR="#CCCCCC" BORDER="1"&gt;    &lt;TR&gt;&lt;TD ALIGN="center"&gt;      &lt;H2&gt;The Online Music Browser&lt;/H2&gt;    &lt;/TD&gt;&lt;/TR&gt;  &lt;/TABLE&gt;    &lt;P&gt;Listed below are the concerts available for download    from this site. Please select an artist from the list at    the left, a concert (or recording) by that artist from    the list in the middle, and a song from the list on the    right. All songs are available in MP3 format. Enjoy.&lt;/P&gt;    &lt;HR NOSHADE&gt;    &lt;FORM NAME="mbrowser" onSubmit="return false"&gt;    &lt;TABLE WIDTH="100%" BORDER="1" BGCOLOR="#CCCCFF"      CELLPADDING="8" CELLSPACING="8"&gt;      &lt;INPUT TYPE="hidden" NAME="selectedRecord" VALUE="-1"&gt;      &lt;TR VALIGN="top"&gt;        &lt;TD&gt;          &lt;B&gt;&lt;BIG&gt;1)&lt;/BIG&gt; Select an Artist:&lt;/B&gt;&lt;BR&gt;          &lt;SELECT NAME="artistList" SIZE="6" onChange="showConcerts(  )"&gt;            &lt;OPTION&gt;Sorry no artists available&lt;/OPTION&gt;          &lt;/SELECT&gt;        &lt;/TD&gt;        &lt;TD&gt;          &lt;B&gt;&lt;BIG&gt;2)&lt;/BIG&gt; Select a Concert:&lt;/B&gt;&lt;BR&gt;          &lt;SELECT NAME="concertList" SIZE="6" onChange="showSongs(  )"&gt;            &lt;OPTION&gt;Please select an artist&lt;/OPTION&gt;          &lt;/SELECT&gt;        &lt;/TD&gt;        &lt;TD&gt;          &lt;B&gt;&lt;BIG&gt;3)&lt;/BIG&gt; Select a Song:&lt;/B&gt;&lt;BR&gt;          &lt;SELECT NAME="songList" SIZE="6" onChange="showSongInfo(  )"&gt;            &lt;OPTION&gt;Please select a concert&lt;/OPTION&gt;          &lt;/SELECT&gt;        &lt;/TD&gt;      &lt;/TR&gt;&lt;TR&gt;        &lt;TD COLSPAN="3" ALIGN="center"&gt;          &lt;H3&gt;Song Information&lt;/H3&gt;          &lt;TABLE BORDER="0"&gt;            &lt;TR&gt;              &lt;TD&gt;&lt;B&gt;Artist:&lt;/B&gt;&lt;/TD&gt;              &lt;TD&gt;&lt;INPUT NAME="artist" TYPE="text" SIZE="40"                onFocus="this.blur(  )"&gt;&lt;/TD&gt;            &lt;/TR&gt;&lt;TR&gt;              &lt;TD&gt;&lt;B&gt;Concert:&lt;/B&gt;&lt;/TD&gt;              &lt;TD&gt;&lt;INPUT NAME="concert" TYPE="text" SIZE="40"                onFocus="this.blur(  )"&gt;&lt;/TD&gt;            &lt;/TR&gt;&lt;TR&gt;              &lt;TD&gt;&lt;B&gt;Song:&lt;/B&gt;&lt;/TD&gt;              &lt;TD&gt;&lt;INPUT NAME="song" TYPE="text" SIZE="40"                onFocus="this.blur(  )"&gt;&lt;/TD&gt;            &lt;/TR&gt;&lt;TR&gt;              &lt;TD&gt;&lt;B&gt;Venue:&lt;/B&gt;&lt;/TD&gt;              &lt;TD&gt;&lt;INPUT NAME="venue" TYPE="text" SIZE="40"                onFocus="this.blur(  )"&gt;&lt;/TD&gt;            &lt;/TR&gt;&lt;TR&gt;              &lt;TD&gt;&lt;B&gt;Date:&lt;/B&gt;&lt;/TD&gt;              &lt;TD&gt;&lt;INPUT NAME="date" TYPE="text" SIZE="20"                onFocus="this.blur(  )"&gt;&lt;/TD&gt;            &lt;/TR&gt;&lt;TR&gt;              &lt;TD&gt;&lt;B&gt;Duration:&lt;/B&gt;&lt;/TD&gt;              &lt;TD&gt;&lt;INPUT NAME="duration" TYPE="text" SIZE="10"                onFocus="this.blur(  )"&gt;&lt;/TD&gt;            &lt;/TR&gt;&lt;TR&gt;              &lt;TD&gt;&lt;B&gt;Download Size:&lt;/B&gt;&lt;/TD&gt;              &lt;TD&gt;&lt;INPUT NAME="size" TYPE="text" SIZE="10"                onFocus="this.blur(  )"&gt;&lt;/TD&gt;            &lt;/TR&gt;          &lt;/TABLE&gt;        &lt;/TD&gt;      &lt;/TR&gt;&lt;TR ALIGN="center"&gt;        &lt;TD  COLSPAN="3"&gt;          &lt;INPUT TYPE="hidden" NAME="filename" VALUE=""&gt;          &lt;INPUT TYPE="button" NAME="download" VALUE="Download Song"            onClick="getSong(  )"&gt;        &lt;/TD&gt;      &lt;/TR&gt;    &lt;/TABLE&gt;  &lt;/FORM&gt;&lt;SCRIPT&gt; &lt;!--&lt;TMPL_VAR NAME="song_data"&gt;// --&gt;&lt;/SCRIPT&gt;  &lt;/BODY&gt;&lt;/HTML&gt;</pre></blockquote></div><p>This <a name="INDEX-1614" />document has a form, but itdoesn't actually submit any queries directly: it has no<a name="INDEX-1615" />submit button and its<a name="INDEX-1616" /><em class="emphasis">onSubmit</em>handler cancels any attempts to submit. The form is simply used as aninterface and includes lists for artist, concert, and song as well asfields for displaying information on selected songs (refer back to<a href="ch07_03.htm#ch07-97838">Figure 7-3</a>).</p><p>In the first <a name="INDEX-1617" /><a name="INDEX-1618" />&lt;SCRIPT&gt;tag, this document loads the <em class="filename">wddx.js</em> file, whichis included in the WDDX SDK available at <a href="http://www.wddx.org/">http://www.wddx.org/</a>. This file contains the<a name="INDEX-1619" /><a name="INDEX-1620" /><a name="INDEX-1621" />JavaScript functions needed tointerpret WDDX objects like recordsets. When the file loads, all ofthe JavaScript code outside of functions and handlers is executed.That sets the <tt class="literal">archive_url</tt> global to the URL of thedirectory where the audio files are located; it also executes theJavaScript code inserted by our CGI script for the &lt;TMPL_VARNAME="song_data"&gt; tag. We'll come back to how thisJavaScript is generated when we look at the CGI script in a moment,but let's peek at the JavaScript code that will be insertedhere. It looks like this:<a href="#FOOTNOTE-10">[10]</a></p><blockquote><a name="FOOTNOTE-10" /><p>[10]Incidentally, all of theartists listed here have released statements affirming that theirpolicy has been to allow their fans to record and distribute theirperformances for noncommercial purposes, and new digital musicformats, such as MP3, do not alter this position. In other words, itis legal to distribute MP3s of their live performances (and a handfulof other recordings released electronically). Obviously, it would be<em class="emphasis">illegal</em> to create a site like this withcopyrighted music.</p></blockquote><blockquote><pre class="code">data=new WddxRecordset(  );data.artist=new Array(  );data.artist[0]="The Grateful Dead";data.artist[1]="The Grateful Dead";data.artist[3]="Widespread Panic";data.artist[4]="Widespread Panic";data.artist[5]="Leftover Salmon";data.artist[6]="The Radiators";...</pre></blockquote><p>The <tt class="literal">data</tt> variable is an object with a property foreach field from our <em class="filename">song_data.txt</em> data file,like <tt class="literal">artist</tt> in this example. Each of theseproperties is an array containing as many entities as there are rowsin the data file.</p><p>As soon as the browser renders the page, the<tt class="function">onLoad</tt> handler calls the<tt class="function">showArtists</tt> function. This function displays theartists by calling <tt class="function">buildList</tt> for the artistselect list object. It then calls the<tt class="function">showConcerts</tt> and <tt class="function">showSongs</tt>functions, which also use the <tt class="function">buildList</tt>function.</p><p>The <tt class="function">buildList</tt> function takes a select listobject, the name of the field to pull the data from, and twoadditional parameters that are the name and value of a field to useas a condition for displaying a record. For example, if you call<tt class="function">buildList</tt> like this:</p><blockquote><pre class="code">buildList( document.mbrowser.concertList, "concert", "artist",  "Widespread Panic" );</pre></blockquote><p>then for every record where the artist is "WidespreadPanic", the value of the <tt class="literal">concert</tt> field isadded it to the <tt class="literal">concertList</tt> select list. If theconditional field name is not provided, then<tt class="function">buildList</tt> adds the requested field for allrecords.</p><p>Initially, the artist list is populated, the concert list has oneentry telling the user to select an artist, and the song list has oneentry telling the user to select a concert. Once the user selects anartist, the concerts by that artist appear in the concert list. Whenthe user selects a concert, the songs from that concert appear in thesongs list. When the user selects a song, the song information isdisplayed in the lower text fields.</p><p>These text fields all have the same handler:</p><blockquote><pre class="code">onFocus="blur(  )"</pre></blockquote><p>This handler essentially makes the text fields uneditable by theuser. As soon as the user tries to click or tab to one of the fields,the cursor immediately leaves the field. This serves no purpose otherthan to indicate that these fields are not intended for user input.If the user is fast enough, it is actually possible to add text tothese fields, but it won't affect anything. These fields arepopulated by the <tt class="function">showSongInfo</tt> function. Thisfunction looks through the data to determine which song has beenselected and then loads the information for this field into the textfields and also sets the hidden <tt class="literal">filename</tt> field.</p><p>When the user clicks on the Download Song button, its<tt class="function">onClick</tt> handler calls the<tt class="function">getSong</tt> function. <tt class="function">getSong</tt>verifies that a song has been selected by checking the value of thefilename field If no song has been selected, the user is notified.Otherwise, the requested song is downloaded in another window.</p><p>Let's look at the CGI script now. Our CGI script must read thedata file, parse it into a WDDX::Recordset object, and add it asJavaScript to our template. The code appears in <a href="ch07_03.htm#ch07-16200">Example 7-5</a>.</p><a name="ch07-16200" /><div class="example"><h4 class="objtitle">Example 7-5. music_browser.cgi </h4><a name="INDEX-1622" /><a name="INDEX-1,623" /><blockquote><pre class="code">#!/usr/bin/perl -wTuse strict;use WDDX;use HTML::Template;use constant DATA_FILE =&gt; "/usr/local/apache/data/music/song_data.txt";use constant TEMPLATE  =&gt; "/usr/local/apache/templates/music/music_browser.tmpl";print "Content-type: text/html\n\n";my $wddx = new WDDX;my $rec = build_recordset( $wddx, DATA_FILE );# Create JavaScript code assigning recordset to variable named "data"my $js_rec = $rec-&gt;as_javascript( "data" );# Output, replacing song_data template var with the JavaScript codemy $tmpl = new HTML::Template( filename =&gt; TEMPLATE );$tmpl-&gt;param( song_data =&gt; $js_rec );print $tmpl-&gt;output;# Takes WDDX object and file path; returns WDDX::Recordset objectsub build_recordset {    my( $wddx, $file ) = @_;    local *FILE;        # Open file and read field names from first line    open FILE, $file or die "Cannot open $file: $!";    my $headings = &lt;FILE&gt;;    chomp $headings;    my @field_names = split /\t/, lc $headings;        # Make each field a string    my @types = map "string", @field_names;    my $rec = $wddx-&gt;recordset( \@field_names, \@types );        # Add each record to our recordset    while (&lt;FILE&gt;) {        	chomp;        my @fields = split /\t/;        $rec-&gt;add_row( \@fields );    }        close FILE;    return $rec;}</pre></blockquote></div><p>This CGI script starts like our previous examples: it adds themodules we need, defines constants to the files it uses, and outputsthe HTTP header. Next, it creates a new WDDX object and constructs a<a name="INDEX-1624" />recordsetvia the <tt class="function">build_recordset</tt> function.</p><p>The <tt class="function">build_recordset</tt> function takes a<em class="filename">WDDX</em> object and a file path. It opens the fileand reads the first line into <tt class="literal">$headings</tt> todetermine the names of the fields. It then splits these into anarray, making sure that each field name is lowercase. The next lineis a little more complex:</p><blockquote><pre class="code">my @types = map "string", @field_names;</pre></blockquote><p><em class="filename">WDDX</em> needs to know the data type for each fieldin the recordset. In this instance, we can treat each field as astring, so this script uses Perl's <tt class="function">map</tt>function to create an array the same size as<tt class="literal">@field_names</tt> with every element set to<tt class="literal">"string"</tt> and assign it to<tt class="literal">@types</tt>. It then gets a new WDDX::Recordset objectand loops through the file, adding each line to the recordset.</p><p>We then convert the recordset into JavaScript code and parse thisinto the template, replacing the <tt class="literal">song_data</tt> tag.That JavaScript code we <a name="INDEX-1625" /> <a name="INDEX-1,626" />discussed <a name="INDEX-1,627" /> <a name="INDEX-1,628" />earlier takes <a name="INDEX-1,629" /> <a name="INDEX-1,630" />over from <a name="INDEX-1,631" /> <a name="INDEX-1,632" />WDDX there.</p></div><hr align="left" width="515" /><div class="navbar"><table border="0" width="515"><tr><td width="172" valign="top" align="left"><a href="ch07_02.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0" /></a></td><td width="171" valign="top" align="center"><a href="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0" /></a></td><td width="172" valign="top" align="right"><a href="ch07_04.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0" /></a></td></tr><tr><td width="172" valign="top" align="left">7.2. Forms</td><td width="171" valign="top" align="center"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0" /></a></td><td width="172" valign="top" align="right">7.4. Bookmarklets</td></tr></table></div><hr align="left" width="515" /><img src="../gifs/navbar.gif" alt="Library Navigation Links" usemap="#library-map" border="0" /><p><font size="-1"><a href="copyrght.htm">Copyright &copy; 2001</a> O'Reilly &amp; Associates. All rights reserved.</font></p><map name="library-map"><area href="../index.htm" coords="1,1,83,102" shape="rect" /><area href="../lnut/index.htm" coords="81,0,152,95" shape="rect" /><area href="../run/index.htm" coords="172,2,252,105" shape="rect" /><area href="../apache/index.htm" coords="238,2,334,95" shape="rect" /><area href="../sql/index.htm" coords="336,0,412,104" shape="rect" /><area href="../dbi/index.htm" coords="415,0,507,101" shape="rect" /><area href="../cgi/index.htm" coords="511,0,601,99" shape="rect" /></map></body></html>

⌨️ 快捷键说明

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