?? ch05_03.htm
字號:
<?label 5.3. Generating Output with CGI.pm?><html><head><title>Generating Output with CGI.pm (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="ch05_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="ch05_04.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0" /></a></td></tr></table></div><hr align="left" width="515" /><h2 class="sect1">5.3. Generating Output with CGI.pm</h2><p><a name="INDEX-1079" /> <a name="INDEX-1,080" /> <a name="INDEX-1,081" />CGI.pm provides a veryelegant solution for outputting both headers and HTML with Perl. Itallows you to embed HTML in your code, but it makes this more naturalby turning the HTML into code. Every<a name="INDEX-1082" />HTML element can begenerated via a corresponding method in <a name="INDEX-1083" /> <a name="INDEX-1,084" />CGI.pm. We have already seensome examples of this already, but here's another:</p><blockquote><pre class="code">#!/usr/bin/perl -wTuse strict;use CGI;my $q = new CGI;my $timestamp = localtime;print $q->header( "text/html" ), $q->start_html( -title => "The Time", -bgcolor => "#ffffff" ), $q->h2( "Current Time" ), $q->hr, $q->p( "The current time according to this system is: ", $q->b( $timestamp ) ), $q->end_html;</pre></blockquote><p>The resulting output looks like this (the indentation is added tomake it easier to read):</p><blockquote><pre class="code">Content-type: text/html<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML> <HEAD><TITLE>The Time</TITLE></HEAD> <BODY BGCOLOR="#ffffff"> <H2>Current Time</H2> <HR> <P>The current time according to this system is: <B>Mon May 29 16:48:14 2000</B></P> </BODY></HTML></pre></blockquote><p>As you can see, the code looks a lot like Perl and a lot less likeHTML. It is also shorter than the corresponding HTML because CGI.pmmanages some common tags for us. Another benefit is that it isimpossible to forget to <a name="INDEX-1085" />close a tag because the methodsautomatically generate closing tags (except for those elements thatCGI.pm knows do not need them, like <HR>).</p><p>We'll look at all of these output methods in this section,starting with the first method, <tt class="function">header</tt>.</p><a name="ch05-14-fm2xml" /><div class="sect2"><h3 class="sect2">5.3.1. Controlling HTTP Headers with CGI.pm</h3><p>CGI.pm has two methods for returning<a name="INDEX-1086" /><a name="INDEX-1087" />HTTP headers:<tt class="function">header</tt> and <tt class="function">redirect</tt>. They correspondto the two ways you can return data from CGI scripts: you can returna document, or you can redirect to another document.</p><a name="ch05-15-fm2xml" /><div class="sect3"><h3 class="sect3">5.3.1.1. Media type</h3><p>The <tt class="function">header</tt> method handles<a name="INDEX-1088" />multiple HTTP headers for you. If youpass it one argument, it returns the<em class="emphasis">Content-type</em><a name="INDEX-1089" /> header with that value. If you do notsupply a media type, it defaults to "text/html". AlthoughCGI.pm makes outputting HTML much easier, you can of course print anycontent type with it. Simply use the <tt class="function">header</tt>method to specify the <a name="INDEX-1090" />media type and then print your content,whether it be text, XML, Adobe PDF, etc.:</p><blockquote><pre class="code">print $q->header( "text/plain" );print "This is just some boring text.\n";</pre></blockquote><p>If you want to set other headers, then you need to pass<a name="INDEX-1091" />name-value pairs for each header. Usethe <tt class="literal">-type</tt> argument to specify the media type (seethe example under <a href="ch05_03.htm#ch05-79140">Section 5.3.1.2, "Status"</a> later in thischapter).</p></div><a name="ch05-79140" /><div class="sect3"><h3 class="sect3">5.3.1.2. Status</h3><p>You can specify a <a name="INDEX-1092" />status other than "200 OK" byusing the <tt class="literal">-status</tt> argument:</p><blockquote><pre class="code">print $q->header( -type => "text/html", -status => "404 Not Found" );</pre></blockquote></div><a name="ch05-16-fm2xml" /><div class="sect3"><h3 class="sect3">5.3.1.3. Caching</h3><p>Browsers <a name="INDEX-1093" /> <a name="INDEX-1,094" /><a name="INDEX-1095" />can't always tell if<a name="INDEX-1096" /> <a name="INDEX-1,097" />content isbeing dynamically generated by CGI or if it is coming from a staticsource, and they may try to cache the output of your script. You candisable this or <a name="INDEX-1098" /><a name="INDEX-1099" />request caching if you want it, byusing the <tt class="literal">-expires</tt> argument. You can supply eithera full time stamp with this argument or a<a name="INDEX-1100" /><a name="INDEX-1101" />relative time. Relative timesare created by supplying a plus or minus sign for forward orbackward, an integer number, and a one letter abbreviation forsecond, minute, hour, day, month, or year (each of theseabbreviations is lowercase except for month, which is an uppercaseM). You can also use "now" to indicate that a documentshould expire immediately. Specifying a negative value also has thiseffect.</p><p>This example tells the browser that this document is good for thenext 30 minutes:</p><blockquote><pre class="code">print $q->header( -type => "text/html", -expires => "+30m" );</pre></blockquote></div><a name="ch05-17-fm2xml" /><div class="sect3"><h3 class="sect3">5.3.1.4. Specifying an alternative target</h3><p>If you are using frames or have multiple windows, you may want<a name="INDEX-1102" /> <a name="INDEX-1,103" /> <a name="INDEX-1,104" />links in one document toupdate another document. You can use the<tt class="literal">-target</tt><a name="INDEX-1105" /> <a name="INDEX-1,106" />argument along with the name of the other document (as set by a<a name="INDEX-1107" /><a name="INDEX-1108" /><FRAMESET>tag or by JavaScript) to specify that clicking on a link in thisdocument should cause the new resource to load in the other frame (orwindow):</p><blockquote><pre class="code">print $q->header( -type => "text/html", -target => "main_frame" );</pre></blockquote><p>This argument is only meaningful for HTML documents.</p></div><a name="ch05-18-fm2xml" /><div class="sect3"><h3 class="sect3">5.3.1.5. Redirection</h3><p>If you need to redirect to another URL, you can use the<tt class="function">redirect</tt><a name="INDEX-1109" /> <a name="INDEX-1,110" /> method instead of printing the<em class="emphasis">Location</em> HTTP header:</p><blockquote><pre class="code">print $q->redirect( "http://localhost/survey/thanks.html" );</pre></blockquote><p>Although the term "redirect" is an action, this methoddoes not perform a redirect for you; it simply returns thecorresponding header. So don't forget you still need to printthe result!</p></div><a name="ch05-19-fm2xml" /><div class="sect3"><h3 class="sect3">5.3.1.6. Other headers</h3><p>If you need to generate other <a name="INDEX-1111" />HTTP headers, you can simplypass the name-value pair to <tt class="function">header</tt> and it willreturn the header with the appropriate formatting. Underscores areconverted to hyphens for you.</p><p>Thus, the following statement:</p><blockquote><pre class="code">print $q->header( -content_encoding => "gzip" );</pre></blockquote><p>produces the following <a name="INDEX-1112" /> <a name="INDEX-1,113" /> <a name="INDEX-1,114" />output:</p><blockquote><pre class="code">Content-encoding: gzip</pre></blockquote></div></div><a name="ch05-20-fm2xml" /><div class="sect2"><h3 class="sect2">5.3.2. Starting and Ending Documents</h3><p>Now let's look <a name="INDEX-1115" /> <a name="INDEX-1,116" /><a name="INDEX-1117" />at the methods that you can use togenerate HTML. We'll start by looking at the methods forstarting and ending documents.</p><a name="ch05-21-fm2xml" /><div class="sect3"><h3 class="sect3">5.3.2.1. start_html</h3><p>The <tt class="function">start_html</tt> method returns the HTML DTD, the<HTML> tag, the <HEAD> section including <TITLE>,and the <BODY> tag. In the previous example, it generates HTMLlike the following:</p><blockquote><pre class="code"><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML><HEAD><TITLE>The Time</TITLE></HEAD><BODY BGCOLOR="#ffffff"></pre></blockquote><p>The most common arguments <tt class="function">start_html</tt> recognizesare as follows:</p><ul><li><p>Setting the <tt class="literal">-base</tt> argument to a true value tellsCGI.pm to include a <a name="INDEX-1118" /><a name="INDEX-1119" /><a name="INDEX-1120" /><BASEHREF="url"> tag in the head of your document that points to theURL of your script.</p></li><li><p>The <tt class="literal">-meta</tt> argument accepts a reference to a hashcontaining the name and content of <a name="INDEX-1121" /><a name="INDEX-1122" /><a name="INDEX-1123" />meta tags that appear in the head of yourdocument.</p></li><li><p>The <tt class="literal">-script</tt><a name="INDEX-1124" /><a name="INDEX-1125" /> argument allows you to addJavaScript to the head of your document. You can either provide astring containing the JavaScript code or a reference to a<a name="INDEX-1126" />hash containing<tt class="literal">-language</tt>, <tt class="literal">-src</tt>, and<tt class="literal">-code</tt> as possible keys. This allows you to specifythe language and source attributes of the<a name="INDEX-1127" /><a name="INDEX-1128" /><SCRIPT> tag too. CGI.pmautomatically provides comment tags around the code to protect itfrom browsers that do not recognize JavaScript.</p></li><li><p>The <tt class="literal">-noscript</tt><a name="INDEX-1129" /><a name="INDEX-1130" /> argument allows you tospecify HTML display if the <a name="INDEX-1131" />browser does not supportJavaScript. It is inserted into the head of your document.</p></li><li><p>The <tt class="literal">-style</tt> argument allows you to define a<a name="INDEX-1132" />style sheet for the document.Like <tt class="literal">-script</tt>, you may either specify a string or areference to a hash. The keys that <tt class="literal">-style</tt> acceptsin the hash are <tt class="literal">-code</tt> and <tt class="literal">-src</tt>.The value of <tt class="literal">-code</tt> will be inserted into thedocument as style sheet information. The value of<tt class="literal">-src</tt> will be a URL to a <em class="filename">.css</em>file. CGI.pm automatically provides<a name="INDEX-1133" />comment tagsaround the code to protect cascading style sheets from browsers thatdo not recognize them.</p></li><li><p>The <tt class="literal">-title</tt> argument sets the<a name="INDEX-1134" />title of the HTML document.</p></li><li><p>The <tt class="literal">-xbase</tt><a name="INDEX-1135" /> <a name="INDEX-1,136" /><a name="INDEX-1137" /> argument lets youspecify a URL to use in the <BASE HREF="url"> tag. This isdifferent from the <tt class="literal">-base</tt> argument that alsogenerates this tag but sets it to the URL of the current CGI script.</p></li></ul><p>Any other arguments, like <tt class="literal">-bgcolor</tt>, are passed asattributes to the <BODY> tag.</p></div><a name="ch05-22-fm2xml" /><div class="sect3"><h3 class="sect3">5.3.2.2. end_html</h3><p>The <em class="emphasis">end_html</em><a name="INDEX-1138" /><a name="INDEX-1139" /><a name="INDEX-1140" /> method returnsthe </BODY> and </HTML> tags.</p></div></div><a name="ch05-23-fm2xml" /><div class="sect2"><h3 class="sect2">5.3.3. Standard HTML Elements</h3><p><a name="INDEX-1141" />HTML elements can begenerated by <a name="INDEX-1142" /> <a name="INDEX-1,143" />using the lowercase name of the element asa method, with the following exceptions: <tt class="function">Accept</tt>,<tt class="function">Delete</tt>, <tt class="function">Link</tt>,<tt class="function">Param</tt>, <tt class="function">Select</tt>,<tt class="function">Sub</tt>, and <tt class="function">Tr</tt>. These methodshave an initial cap to avoid conflicting with built-in Perl functionsand other CGI.pm methods.</p><p>The following rules apply to basic <a name="INDEX-1144" /><a name="INDEX-1145" />HTML tags:</p><ul><li><p>CGI.pm recognizes that some elements, like <HR> and <BR>,do not have <a name="INDEX-1146" />closing tags. Thesemethods take no arguments and return the single tag:</p><blockquote><pre class="code">print $q->hr;</pre></blockquote><p>This outputs:</p><blockquote><pre class="code"><HR></pre></blockquote></li><li><p>If you provide one argument, it creates an opening and closing tag toenclose the text of your argument. Tags are capitalized:</p><blockquote><pre class="code">print $q->p( "This is a paragraph." );</pre></blockquote><p>This prints the text:</p><blockquote><pre class="code"><P>This is a paragraph.</P></pre></blockquote></li><li><p>If you provide multiple arguments, these are simply joined with thetags at the beginning and the end:</p><blockquote><pre class="code">print $q->p( "The server name is:", $q->server_name );</pre></blockquote><p>This prints the text:</p><blockquote><pre class="code"><a name="INDEX-1147" /><P>The server name is: localhost</P></pre></blockquote>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -