📄 ch07_03.htm
字号:
<?label 7.3. Data Exchange?><html><head><title>Data Exchange (CGI Programming with Perl)</title><link href="../style/style1.css" type="text/css" rel="stylesheet" /><meta name="DC.Creator" content="Scott Guelich, Gunther Birznieks and Shishir Gundavaram" /><meta scheme="MIME" content="text/xml" name="DC.Format" /><meta content="en-US" name="DC.Language" /><meta content="O'Reilly & Associates, Inc." name="DC.Publisher" /><meta scheme="ISBN" name="DC.Source" content="1565924193L" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="CGI Programming with Perl" /><meta content="Text.Monograph" name="DC.Type" /></head><body bgcolor="#ffffff"><img src="gifs/smbanner.gif" alt="Book Home" usemap="#banner-map" border="0" /><map name="banner-map"><area alt="CGI Programming with Perl" href="index.htm" coords="0,0,466,65" shape="rect" /><area alt="Search this book" href="jobjects/fsearch.htm" coords="467,0,514,18" shape="rect" /></map><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">CGI Programming with Perl</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></table></div><hr align="left" width="515" /><h2 class="sect1">7.3. Data Exchange</h2><p>If you place enough functionality in <a name="INDEX-1586" /> <a name="INDEX-1,587" />JavaScript-enabled web pages, theycan become <a name="INDEX-1588" /><a name="INDEX-1589" />semiautonomousclients that the user can interact with independent of CGI scripts onthe server. The most recent versions of JavaScript provide theability to create queries to web servers, load the response in hiddenframes, and react to this data. In response to queries such as these,CGI scripts are not outputting HTML; they're typicallyoutputting raw data that is being handled by another application.We'll explore the concept of <a name="INDEX-1590" /><a name="INDEX-1591" />information servers further whenwe'll discuss XML in <a href="ch14_01.htm">Chapter 14, "Middleware and XML"</a>.</p><p>As JavaScript's abilities have expanded, one question that webdevelopers sometimes ask is how they can move their complex datastructures from their Perl CGI scripts into JavaScript. Perl andJavaScript are different languages with different data structures, soit can be challenging creating dynamic JavaScript.</p><a name="ch07-8-fm2xml" /><div class="sect2"><h3 class="sect2">7.3.1. WDDX</h3><p>Exchanging <a name="INDEX-1592" /><a name="INDEX-1593" /><a name="INDEX-1594" /> <a name="INDEX-1,595" />data betweendifferent languages isn't a new challenge of course, andfortunately someone else has already addressed this same problem.Allaire, the makes of Cold Fusion, wanted a way to exchange databetween different web servers on the Internet. Their solution, WebDistributed Data Exchange, or <em class="firstterm">WDDX</em>, defines acommon data format that various languages can use to represent basicdata types. WDDX uses <a name="INDEX-1596" />XML, but you don't need to knowanything about XML to use WDDX because there are modules that providea simple interface for using it in many languages including Perl andJavaScript. Thus, we can convert a Perl data structure into a WDDXpacket that can then be converted into a native data structure inJavaScript, Java, COM (this includes Active Server Pages),ColdFusion, or PHP.</p><p>However, with JavaScript, we can even skip the intermediate step.Because converting data to JavaScript is such a common need on theWeb,<a name="INDEX-1597" /><a name="INDEX-1598" />WDDX.pm,the Perl module for WDDX, will convert a Perl data structure intoJavaScript code that can create a corresponding JavaScript datastructure without creating a WDDX packet.</p><p>Let's look at an example to see how this works. Say that youwant to pass the current date on the web server from your<a name="INDEX-1599" />CGI script toJavaScript. In Perl, the date is measured by the number of secondspast the epoch; it looks like this:</p><blockquote><pre class="code">my $now = time;</pre></blockquote><p>To create JavaScript from this, you would use the following code:</p><blockquote><pre class="code">use WDDX;my $wddx = new WDDX;my $now = time;my $wddx_now = $wddx->datetime( $now );print $wddx_now->as_javascript( "serverTime" );</pre></blockquote><p>We create a WDDX.pm object and then pass the time to the<tt class="function">datetime</tt> method, which returns a WDDX::Datetimeobject. We can then use the <tt class="function">as_javascript</tt> methodto get JavaScript code for it. This outputs something like thefollowing (the date and time will of course be different when you runit):</p><blockquote><pre class="code">serverTime=new Date(100,0,5,14,20,39);</pre></blockquote><p>You can include this within an HTML document as JavaScript code.Dates are created very differently in JavaScript than in Perl butWDDX will handle this translation for you. DateTime is just one datatype that WDDX supports. WDDX defines several basic data types thatare common to several programming languages. The WDDX<a name="INDEX-1600" /> <a name="INDEX-1,601" />data types are <a name="INDEX-1,602" /><a name="INDEX-1603" />summarized in <a href="ch07_03.htm#ch07-23265">Table 7-1</a>.</p><a name="ch07-23265" /><h4 class="objtitle">Table 7-1. WDDX Data Types </h4><table border="1"><tr><th><p>WDDX Type</p></th><th><p>WDDX.pm Data Object</p></th><th><p>Perl Type</p></th></tr><tr><td><p>String</p></td><td><p>WDDX::String</p></td><td><p>Scalar</p></td></tr><tr><td><p>Number</p></td><td><p>WDDX::Number</p></td><td><p>Scalar</p></td></tr><tr><td><p>Boolean</p></td><td><p>WDDX::Boolean</p></td><td><p>Scalar (1 or " ")</p></td></tr><tr><td><p>Datetime</p></td><td><p>WDDX::Datetime</p></td><td><p>Scalar (seconds since epoch)</p></td></tr><tr><td><p>Null</p></td><td><p>WDDX::Null</p></td><td><p>Scalar (undef)</p></td></tr><tr><td><p>Binary</p></td><td><p>WDDX::Binary</p></td><td><p>Scalar</p></td></tr><tr><td><p>Array</p></td><td><p>WDDX::Array</p></td><td><p>Array</p></td></tr><tr><td><p>Struct</p></td><td><p>WDDX::Struct</p></td><td><p>Hash</p></td></tr><tr><td><p>Recordset</p></td><td><p>WDDX::Recordset</p></td><td><p>None (WDDX::Recordset)</p></td></tr></table><p>As you can see, the WDDX data types are different from Perl'sdata types. Perl represents many different data types as<a name="INDEX-1604" />scalars. As a result, the WDDX.pm moduleworks differently than similar WDDX libraries for other languages,which are more transparent. In these other languages, you can use onemethod to go directly from the native data type to a WDDX packet (orJavaScript code). Because of the differences with the data types inPerl, WDDX.pm requires that you create an intermediate data object,such as <tt class="literal">$wddx_now</tt>, the WDDX::Datetime object thatwe saw above, which can then be converted to a WDDX packet or nativeJavaScript code.</p><p>Although originally conceived by Allaire, <a name="INDEX-1605" />WDDX has been released as an opensource project. You can download the WDDX SDK from <a href="http://www.wddx.org/">http://www.wddx.org/</a>; the WDDX.pm module isavailable on CPAN.</p></div><a name="ch07-9-fm2xml" /><div class="sect2"><h3 class="sect2">7.3.2. Example</h3><p><a name="INDEX-1606" /><a name="INDEX-1607" />WDDX.pmis most useful for <a name="INDEX-1608" /> <a name="INDEX-1,609" />complex data structures, solet's look at another example. We'll use JavaScript andHTML to create an interactive <a name="INDEX-1610" /> <a name="INDEX-1,611" />formthat allows users to browse songs available for download (see <a href="ch07_03.htm#ch07-97838">Figure 7-3</a>). Users can look through the song databasewithout making additional calls to the web server until they havefound a song they want to download.</p><p>We'll maintain the song information in a tab-delimited file onthe web server with the format shown in <a href="ch07_03.htm#ch07-61755">Example 7-3</a>.</p><a name="ch07-61755" /><div class="example"><h4 class="objtitle">Example 7-3. song_data.txt </h4><blockquote><pre class="code">Artist Concert Song Venue Date Duration Size Filename...</pre></blockquote></div><p>This record-based format is the same that is used by a spreadsheet ora database, and it is represented in WDDX as a<a name="INDEX-1612" />recordset. Arecordset is simply a series of records (or rows) that share acertain number of named fields (or columns).</p><p>Let's look at the HTML and JavaScript for the file. Note thatthis version requires that the user have JavaScript; this form willnot contain any information without it. In practice, you wouldprobably want to add a more basic interface within <NOSCRIPT>tags to support non-JavaScript users.</p><a name="ch07-97838" /><div class="figure"><img width="481" src="figs/cgi2.0703.gif" height="436" alt="Figure 7-3" /></div><h4 class="objtitle">Figure 7-3. Online music browser</h4><p>A CGI script will output this file when it is requested, but the onlything our CGI script must add is the data for the music. Thus, in<a href="ch07_03.htm#ch07-40220">Example 7-4</a>, we'll use HTML::Template to passone variable into our file; that tag appears near the bottom.</p><a name="ch07-40220" /><div class="example"><h4 class="objtitle">Example 7-4. music_browser.tmpl </h4><a name="INDEX-1613" /><blockquote><pre class="code"><HTML><HEAD> <TITLE>Online Music Browser</TITLE> <SCRIPT SRC="/js-lib/wddx.js"></SCRIPT> <SCRIPT> <!-- var archive_url = "http://www.some-mp3-site.org/downloads/"; function showArtists( ) { var artists = document.mbrowser.artistList; buildList( artists, "artist", "", "" ); if ( artists.options.length == 0 ) { listMsg( artists, "Sorry no artists available now" ); } showConcerts( ); showSongs( ); } function showConcerts( ) { var concerts = document.mbrowser.concertList; if ( document.mbrowser.artistList.selectedIndex < 0 ) { var selected = selectedValue( document.mbrowser.artistList ); buildList( concerts, "concert", "artist", selected ); } else { listMsg( concerts, "Please select an artist" ); } showSongs( ); } function showSongs( ) { var songs = document.mbrowser.songList; songs.options.length = 0; songs.selectedIndex = -1; if ( document.mbrowser.concertList.selectedIndex < 0 ) { var selected = selectedValue( document.mbrowser.concertList ); buildList( songs, "song", "concert", selected ); } else { listMsg( songs, "Please select a concert" ); } } function buildList( list, field, conditionField, conditionValue ) { list.options.length = 0; list.selectedIndex = -1; var showAll = ! conditionField; var list_idx = 0; var matched = new Object; // Used as hash to avoid duplicates for ( var i = 0; i < data[field].length; i++ ) { if ( ! matched[ data[field][i] ] && ( showAll || data[conditionField][i] == conditionValue ) ) { matched[ data[field][i] ] = 1; var opt = new Option( ); opt.text = data[field][i]; opt.value = data[field][i]; list.options[list_idx++] = opt; } } } function showSongInfo( ) { var form = document.mbrowser; var idx = -1; for ( var i = 0; i < data.artist.length; i++ ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -