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

📄 ch07_02.htm

📁 用perl编写CGI的好书。本书从解释CGI和底层HTTP协议如何工作开始
💻 HTM
📖 第 1 页 / 共 2 页
字号:
            &lt;/select&gt;          &lt;/td&gt;&lt;/tr&gt;        &lt;tr&gt;          &lt;td colspan=2 align=right&gt;            &lt;input type="submit"&gt;          &lt;/td&gt;&lt;/tr&gt;      &lt;/table&gt;    &lt;/form&gt;      &lt;/body&gt;&lt;/html&gt;</pre></blockquote></div><p>You don't see much JavaScript here because most of it is in<a name="INDEX-1559" /><a name="INDEX-1560" />aseparate file that is included with the following pair of tags online 5:</p><blockquote><pre class="code">&lt;script src="/js-lib/formLib.js" &gt;&lt;/script&gt;</pre></blockquote><p>The contents of <em class="emphasis">formLib.js</em><a name="INDEX-1561" /><a name="INDEX-1562" /> <a name="INDEX-1,563" /> are shown in <a href="ch07_02.htm#ch07-17670">Example 7-2</a>.</p><a name="ch07-17670" /><div class="example"><h4 class="objtitle">Example 7-2. formLib.js </h4><blockquote><pre class="code">// formLib.js// Common functions used with forms// // We use this as a hash to track those elements validated on a per element// basis that have formatting problemsvalidate = new Object(  );// Takes a value, checks if it's an integer, and returns true or falsefunction isInteger ( value ) {    return ( value == parseInt( value ) );}// Takes a value and a range, checks if the value is in the range, and// returns true or falsefunction inRange ( value, low, high ) {    return ( !( value &lt; low ) &amp;&amp; value &lt;= high );}// Checks values against formats such as '#####' or '###-##-####'function checkFormat( value, format ) {    var formatOkay = true;    if ( value.length != format.length ) {        return false;    }    for ( var i = 0; i &lt; format.length; i++ ) {        if ( format.charAt(i) == '#' &amp;&amp; ! isInteger( value.charAt(i) ) ) {            return false;        }        else if ( format.charAt(i) != '#' &amp;&amp;                  format.charAt(i) != value.charAt(i) ) {            return false;        }    }    return true;}// Takes a form and an array of element names; verifies that each has a valuefunction requireValues ( form, requiredValues ) {    for ( var i = 0; i &lt; requiredValues.length; i++ ) {        element = requiredText[i];        if ( form[element].value == "" ) {            alert( "Please enter a value for " + element + "." );            return false;        }    }    return true;}// Takes a form and an array of element names; verifies that each has an// option selected (other than the first; assumes that the first option in// each select menu contains instructions)function requireSelects ( form, requiredSelect ) {    for ( var i = 0; i &lt; requiredSelect.length; i++ ) {        element = requiredSelect[i];        if ( form[element].selectedIndex &lt;= 0 ) {            alert( "Please select a value for " + element + "." );            return false;        }    }    return true;}// Takes a form and an array of element names; verifies that each has a// value checkedfunction requireRadios ( form, requiredRadio ) {    for ( var i = 0; i &lt; requiredRadio.length; i++ ) {        element = requiredRadio[i];        isChecked = false;        for ( j = 0; j &lt; form[element].length; j++ ) {            if ( form[element][j].checked ) {                isChecked = true;            }        }        if ( ! isChecked ) {            alert( "Please choose a " + form[element][0].name + "." );            return false;        }    }    return true;}// Verify there are no uncorrected formatting problems with elements// validated on a per element basisfunction checkProblems (  ) {    for ( element in validate ) {        if ( ! validate[element] ) {            alert( "Please correct the format of " + element + "." );            return false;        }    }    return true;}// Verifies that the value of the provided element has ##### formatfunction checkZip ( element ) {    if ( ! checkFormat( element.value, "#####" ) ) {        alert( "Please enter a five digit zip code." );        element.focus(  );        validate[element.name] = false;    }    else {        validate[element.name] = true;    }    return validate[element.name];}// Verifies that the value of the provided element has ###-###-#### formatfunction checkPhone ( element ) {     if ( ! checkFormat( element.value, "###-###-####" ) ) {        alert( "Please enter " + element.name + " in 800-555-1212 " +               "format." );        element.focus(  );        validate[element.name] = false;    }    else {        validate[element.name] = true;    }    return validate[element.name];}// Verifies that the value of the provided element has ###-##-#### formatfunction checkSSN ( element ) {    if ( ! checkFormat( element.value, "###-##-####" ) ) {        alert( "Please enter your Social Security Number in " +               "123-45-6789 format." );        element.focus(  );        validate[element.name] = false;    }    else {        validate[element.name] = true;    }    return validate[element.name];}// Verifies that the value of the provided element is an integer between 1 and 150function checkAge ( element ) {    if ( ! isInteger( element.value ) ||         ! inRange( element.value, 1, 150 ) ) {        alert( "Please enter a number between 1 and 150 for age." );        element.focus(  );        validate[element.name] = false;    }    else {        validate[element.name] = true;    }    return validate[element.name];}</pre></blockquote></div><p>We use both types of validation in this example: validating<a name="INDEX-1564" />elements as they are entered andvalidating the form as a whole when it is submitted. We create a<tt class="literal">validate</tt> object that we use like a Perl hash.Whenever we validate an element, we add the name of this element tothe <tt class="literal">validate</tt> object and set it to true or falsedepending on whether the element has the correct format. When theform is <a name="INDEX-1565" /><a name="INDEX-1566" />submitted,we later loop over each element in <tt class="literal">validate</tt> todetermine if there are any elements that had formatting problems andwere not fixed.</p><p>The <a name="INDEX-1567" />functions that handlespecific field validation are <tt class="function">checkZip</tt>,<tt class="function">checkPhone</tt>, <tt class="function">checkSSN</tt>, and<tt class="function">checkAge</tt>. They are called by the<tt class="function">onChange</tt><a name="INDEX-1568" /> handler for each of these formelements and the functions appear at the bottom of<em class="filename">formLib.js</em>. Each of these functions use the moregeneral functions <tt class="function">isInteger</tt>,<tt class="function">isRange</tt>, or <tt class="function">checkFormat</tt> tocheck the formatting of the element they are validating.<tt class="function">isInteger</tt> and <tt class="function">isRange</tt> aresimple checks that return whether a value is an integer or whether itis within a particular numeric range.</p><p><tt class="function">checkFormat</tt><a name="INDEX-1569" /> takes a value as well as astring containing a format to check the value against. The structureof our format string is quite simple: a pound symbol represents anumeric digit and any other character represents itself. Of course,in Perl we could easily do checks like this with a regularexpression. For example, we could match social security number with<tt class="literal">/^\d\d\d-\d\d-\d\d\d\d$/</tt>. Fortunately, JavaScript1.2 also supports <a name="INDEX-1570" />regular expressions. Unfortunately, thereare still many <a name="INDEX-1571" />browsers on the Internet that only supportJavaScript 1.1, most notably Internet Explorer 3.0.</p><p>When the form is submitted, the <tt class="function">onSubmit</tt> handlercalls the <tt class="function">validateForm</tt> function. This functionbuilds an array of elements such as text boxes that require values,an array of select list elements that require a selection, and anarray of radio button group elements that require a checked value.These lists are passed to <tt class="function">requireValues</tt>,<tt class="function">requireSelects</tt>, and<tt class="function">requireRadios</tt>, respectively, which verify thatthese elements have been filled in by the user.</p><p>Finally, the<tt class="function">checkProblems</tt><a name="INDEX-1572" /> function loops over theproperties in the validate object and returns a boolean valueindicating whether there are any elements that still have formattingproblems. If <tt class="function">requireValues</tt>,<tt class="function">requireSelects</tt>,<tt class="function">requireRadios</tt>, or<tt class="function">checkProblems</tt> fail, then they display anappropriate message to the user and return false, which cancels thesubmission of the form. Otherwise, the form is submitted to the CGIscript which handles the query like any other request. In this case,the CGI script would record the data in a file or database. Wewon't look at the CGI script here, although we will discusssaving data like this <a name="INDEX-1573" /> <a name="INDEX-1,574" /> <a name="INDEX-1,575" />on the <a name="INDEX-1,576" /> <a name="INDEX-1,577" />server in <a href="ch10_01.htm">Chapter 10, "Data Persistence"</a>.</p></div><a name="ch07-7-fm2xml" /><div class="sect3"><h3 class="sect3">7.2.1.4. Validating twice</h3><p>Note that we said that the <a name="INDEX-1578" /><a name="INDEX-1579" />CGI script would handle a request comingfrom a page with JavaScript validation just like it would handle anyother request. When you do data validation with JavaScript,there's an important maxim you need to keep in mind:<em class="emphasis">Never rely on the client to do your data validation foryou.</em><a name="INDEX-1580" />When you develop CGI scripts, youshould <em class="emphasis">always</em> validate the data you receive,whether the data is coming from a form that performs JavaScriptvalidation or not. Yes, this means that we are performing the samefunction twice. The theory behind this is that you should never trustdata that comes from the client without checking it yourself. As wementioned earlier, JavaScript may be supported by the user'sbrowser or it may be turned off. Thus, you cannot rely on JavaScriptvalidation being performed. For a more detailed discussion of why itis a bad idea to trust the user, refer to <a href="ch08_01.htm">Chapter 8, "Security"</a>.</p><p>Thus, we may often write our data validation code twice, once inJavaScript for the client, and again in our CGI script. Some mayargue that it is poor design to write the same code twice, and theyare right in that avoiding duplicate code is a good principle ofdesigning maintainable code. However, in this situation, we canprovide two counter-arguments.</p><p>First, we need to do data validation in the CGI script because it isalso good programming practice for each component to validate itsinput. The JavaScript code is part of the client user interface; itreceives data from the user and validates it in preparation forsending it to the server. It sends the data on to the CGI script, butthe CGI script must again validate that the input it receives is inthe proper format because the it doesn't know (nor should itcare) what processing the client did or did not do on its end.Similarly, if our CGI script then calls a database, the database willagain validate the input that we sent on to it, etc.</p><p>Second, we gain much by doing JavaScript validation because it letsus validate as close to the user as possible. If we perform datavalidation on the client using JavaScript, we avoid unnecessarynetwork connections because if JavaScript notices an invalid entry,it can immediately notify the user who can correct the form before itis submitted. Otherwise, the client must submit the form to theserver, a CGI script must validate the input and return a pagereporting the error and allowing the user to fix the problem. Ifthere are multiple errors, it may take a few tries to get it right.</p><p>In many cases, performing the extra check with JavaScript is worththe trade-off. When deciding whether to use JavaScript validationyourself, consider how often you expect the interface and the formatof the data to change and how much extra effort is involved inmaintaining JavaScript validation code in addition to CGI scriptvalidation code. You <a name="INDEX-1581" /> <a name="INDEX-1,582" /> <a name="INDEX-1,583" /> <a name="INDEX-1,584" />can then weigh this <a name="INDEX-1,585" />effort against theconvenience to the user.</p></div></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_01.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_03.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0" /></a></td></tr><tr><td width="172" valign="top" align="left">7. JavaScript</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.3. Data Exchange</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 + -