XMLHttpRequest创建智能表单

来源:岁月联盟 编辑:zhuzhu 时间:2009-02-18

16.4  使用XMLHttpRequest创建智能表单

我们可能已经多次遇到过这样的情况:当通过某个Web站点的表单注册用户,或者申请注册一个基于Web界面的电子邮箱时,在我们填写完长长的表单之后,结果却发现我们申请的用户名已经被其他人占用了。最糟糕的就是直到我们填完表单并提交,且页面被重新加载之后,我们才能发现所申请的用户名是否已经被他人使用,并且重新加载页面之后我们已经输入的某些信息就可能已经丢失,我们不得不再次重新输入这些信息。幸运的是,Ajax可以消除这种令人沮丧的用户体验,并在用户提交表单之前,告诉用户他所申请的用户名是否可用。

我们可以采用多种不同的方法来解决这一问题,最简单的办法就是提供一个超链接以发起一个到目标服务器程序的HTTP请求,以检查用户申请的用户名等信息是否可用。

下面我们将创建一个类似于常见注册页面的表单。该表单将包含以下几个字段:

●       Username(须校验字段)—— 用户在该字段中输入希望申请的用户名。

●       Email(须校验字段)—— 用户在该字段中输入他的e-mail。

●       Password(无须校验字段)—— 用户在该字段中输入他的密码。

●       Verify Password(无须校验字段)—— 用户在该字段中再次输入密码,与前一次输入的密码进行比较,以检查两次输入的密码是否一致。

注意,在本例中,Password和Verify Password字段仅仅作为表单的字段进行演示。实际上,密码校验是由服务器端的程序和数据库来完成的,但是,在提交表单之前,可以使用JavaScript来检查两次输入的密码是否一致,这比将两个密码的检查放在服务器端更加有效率。

在Username和Email字段之后,将包含一个超链接,该超链接将调用一个JavaScript函数,并使用本章前面创建的HttpRequest类来发起一个请求,以向目标服务器查询当前用户输入的Username或Email是否有效。服务器端的程序是一个简单的PHP程序文件。虽然关于PHP程序设计的相关内容并不在本书的范围,但是我们将讨论一下如何向该PHP程序发起请求以验证数据,以及如何将响应返回的数据回送给JavaScript使用。

16.4.1  如何向服务器端的PHP程序查询信息

服务器端的PHP程序将在查询字符串中查找以下两个参数:username参数或者email参数。

要检查用户名是否可用,只需使用username参数。一个请求查询用户名是否可用的查询字符串将如下所示:

http://localhost/formvalidator.php?username=[usernameToSearchFor]

当实际查询某一个用户名时,只需将[usernameToSearchFor]替换为实际要查询的用户名即可。

查询e-mail的方法与此类似。一个查询e-mail是否有效的URL将如下所示:

http://localhost/formvalidator.php?email=[emailToSearchFor]

16.4.2  从服务器返回的数据

如果查询请求成功,则将返回以下两个值之一:

●       available—— 该值表示所查询的用户名或e-mail有效。

●       not available—— 该值表示所查询的用户名或e-mail已经被注册,因此当前所输入的注册信息无效。

从服务器端返回的值将以纯文本的方式发送给客户端。客户端JavaScript只须通过一个简单的比较,即可告诉用户他所输入的用户名或e-mail是否已经被注册。

16.4.3  在开始编写代码之前

由于这是一个在线的(live-code)Ajax实例,因此要运行该实例,计算机必须满足如下所示的几点要求。

1. 计算机上必须有一个Web服务器

首先,PHP程序必须运行在一个Web服务器上,因此必须在计算机上安装一个Web服务器。如果你使用的是Windows 2000(个人版或服务器版)、Windows XP Professional或者Windows Server 2003,则这些操作系统中已经提供了一个免费的Web服务器以供使用,即Internet Information Services(IIS)。要安装IIS服务器,只需在Windows操作系统的控制面板中打开Add/Remove Programs,并单击Add/Remove Windows Components即可。图16-3展示了Windows XP Professional系统中的Windows Components Wizard窗口。

只需选中Internet Information Services(IIS)选项前面的复选框,然后单击Next按钮即可进行安装。安装时可能需要使用操作系统的安装光盘,以完成IIS的安装。

如果你所使用的不是以上几种操作系统,或者你希望使用其他的Web服务器,那么你可以下载并安装一个Apache HTTP Server(www.apache.org)。Apache HTTP Server是一个开放源代码的Web服务器,它可以运行在多种操作系统之上,如Linux系统、Unix系统和Windows系统等。

图  16-3

2. PHP

PHP是一种比较流行的开放源代码的服务器端脚本语言。如果想运行PHP脚本,必须在计算机上安装PHP。从www.php.net上可以下载到各种形式的PHP安装程序(如二进制形式、Windows安装向导形式、或者PHP的源代码形式)。本例中的PHP代码是用PHP 4编写的,但在PHP 5中这些代码也能照常运行。

 

打开文本编辑器并输入下列代码:

<html>

<head>

<title>Form Field Validation</title>

<style type="text/css">

.fieldname

{

text-align: right;

}

.submit

{

text-align: right;

}

</style>

<script type="text/javascript" src="HttpRequest.js"></script>

<script type="text/javascript">

function checkUsername()

{

var userValue = document.getElementById("username").value;

if (userValue == "")

{

alert("Please enter a user name to check!");

return;

}

var url = "formvalidator.php?username=" + userValue;

var request = new HttpRequest(url, checkUsername_callBack);

request.send();

}

function checkUsername_callBack(sResponseText)

{

var userValue = document.getElementById("username").value;

if (sResponseText == "available")

{

alert("The username " + userValue + " is available!");

}

else

{

alert("We’re sorry, but " + userValue + " is not available.");

}

}

function checkEmail()

{

var emailValue = document.getElementById("email").value;

if (emailValue == "")

{

alert("Please enter an email address to check!");

return;

}

var url = "formvalidator.php?email=" + emailValue;

var request = new HttpRequest(url, checkEmail_callBack);

request.send();

}

function checkEmail_callBack(sResponseText)

{

var emailValue = document.getElementById("email").value;

if (sResponseText == "available")

{

alert("The email " + emailValue + " is currently not in use!");

}

else

{

alert("I’m sorry, but " + emailValue + " is in use by another user.");

}

}

</script>

</head>

<body>

<form>

<table>

<tr>

<td class="fieldname">

Username:

</td>

<td>

<input type="text" id="username" />

</td>

<td>

<a href="javascript: checkUsername()">Check Availability</a>

</td>

</tr>

<tr>

<td class="fieldname">

Email:

</td>

<td>

<input type="text" id="email" />

</td>

<td>

<a href="javascript: checkEmail()">Check Availability</a>

</td>

</tr>

<tr>

<td class="fieldname">

Password:

</td>

<td>

<input type="text" id="password" />

</td>

<td />

</tr>

<tr>

<td class="fieldname">

Verify Password:

</td>

<td>

<input type="text" id="password2" />

</td>

<td />

</tr>

<tr>

<td colspan="2" class="submit">

<input type="submit" value="Submit" />

</td>

<td />

</tr>

</table>

</form>

</body>

</html>

将上面的代码保存在Web服务器的根目录中。如果你使用的Web服务器是IIS,则将上面的代码保存为c:/inetpub/wwwroot/validate_form.htm文件。如果你使用的Web服务器是Apache,则可将上面的代码保存在htdocs文件夹之下,即保存为pathTohtdocs/htdocs/validate_form.htm文件。

另外,我们还需要将httprequest.js文件(定义了HttpRequest类)和formvalidator.php文件放在与validate_form.htm文件相同的目录中。

现在,我们可以打开浏览器,在地址栏中输入http://localhost/formvalidator.php。如果Web服务器工作正常的话,你将看到页面上显示出“PHP is working correctly. Congratulations!”这样一段文本信息,如图16-4所示。

图  16-4

接下来,如果在浏览器的地址栏中输入http://localhost/validate_form.htm,你将看到一个如图16-5所示的页面。

图  16-5

在Username文本框中输入jmcpeak,并单击文本框旁边的Check Availability超链接,你将看到一个弹出的信息对话框,如图16-6所示。

图  16-6

接下来,在Email文本框中输入someone@xyz.com,并单击文本框旁边的Check Availability超链接。你将看到一个消息对话框弹出,并提示你该E-mail已经被注册了。我们还可以在Username文本框和Email文本框中输入我们自己的用户名和E-mail地址,并单击文本框旁边相应的超链接进行检查。也许信息对话框将告诉你所输入的用户名或E-mail是有效的(注意:在服务器端的PHP程序中,假定了用户名jmcpeak和pwilton,电子邮箱someone@xyz.com和someone@zyx.com已经被注册)。

代码解说

该HTML页面中包含一个简单的表单,表单中的各个字段通过一个表格来进行页面布局的处理。在表格中,每一个表单字段占用一个表格行。表格的前两行就是我们最感兴趣的字段,即Username字段和Email字段。相应的HTML代码如下所示:

<form>

<table>

<tr>

<td class="fieldname">

Username:

</td>

<td>

<input type="text" id="username" />

</td>

<td>

<a href="javascript: checkUsername()">Check Availability</a>

</td>

</tr>

<tr>

<td class="fieldname">

Email:

</td>

<td>

<input type="text" id="email" />

</td>

<td>

<a href="javascript: checkEmail()">Check Availability</a>

</td>

</tr>

<!-- HTML to be continued later -->

表格的第一列包含了字段的标题。第二列则包含了<input/>元素本身。这些标记都有id属性,username用于Username域,email用于Email域。这使用户可以很容易地找到<input/>元素并将文本输入其中。第三列中则包含了一个相应的超链接(<a/>元素),该超链接使用JavaScript:协议来调用JavaScript代码。在本例中,当用户单击Username字段之后的超链接时,将调用checkUsername()函数,当用户单击了Email字段之后的超链接时,将调用checkEmail()函数。稍后我们将讨论这两个函数。

表格的其余三行包含了两个密码字段和一个Submit按钮(在本例的表单中并不涉及这几个字段)。其前两行同样也包含了三列:第一列是描述性的字段标题,第二列则包含了<input/>元素,第三列为空。定义这三个表格行的HTML代码如下所示:

<!-- HTML continued from earlier -->

<tr>

<td class="fieldname">

Password:

</td>

<td>

<input type="text" id="password" />

</td>

<td />

</tr>

<tr>

<td class="fieldname">

Verify Password:

</td>

<td>

<input type="text" id="password2" />

</td>

<td />

</tr>

<tr>

<td colspan="2" class="submit">

<input type="submit" value="Submit" />

</td>

<td />

</tr>

</table>

</form>

最后一行则包含了两个单元格。第一个单元格跨越了表格的两列,其中包含了表单的Submit按钮。第二个单元格则为空。

该HTML页面中的CSS仅包含了如下所示的两个样式规则:

.fieldname

{

text-align: right;

}

.submit

{

text-align: right;

}

这两个样式规则用于设置表格中元素的对齐方式,以使表单看上去整齐而有序。

在这个实例中,字段之后的超链接是实现Ajax功能的关键,当单击超链接时将调用相应的JavaScript函数。首先,我们来讨论一下第一个函数checkUsername(),该函数用以获取用户在Username文本框中输入的用户名,并使用该信息执行一个HTTP请求。

function checkUsername()

{

var userValue = document.getElementById("username").value;

if (userValue == "")

{

alert("Please enter a user name to check!");

return;

}

var url = "formvalidator.php?username=" + userValue;

var request = new HttpRequest(url, checkUsername_callBack);

request.send();

}

在上面的代码中,为了获取用户名,使用了document.getElementById()方法以引用该<input/>元素,使用value属性以获取用户在username文本框中输入的用户名,并将用户名保存在变量userValue中。接下来,将变量userValue的值与空字符串(" ")进行比较。如果username文本框中的值为空,则提示用户输入用户名,并使用return语句返回以结束函数的执行。如果不对用户名为空的情况进行检查,则可能会向服务器发送一些不必要的请求。

在checkUsername()中,接下来的代码构造了一个URL字符串并将其保存在变量url中,该URL是一个向目标服务器PHP程序发送请求的查询字符串。随后,创建了一个HttpRequest对象,将URL和回调函数传递给HttpRequest()构造函数,并向目标服务器发送请求。

当HttpRequest对象成功地从服务器获得响应之后,回调函数checkUsername_callBack()将被执行。该函数将根据请求返回的信息告诉用户所申请的用户名是否有效。注意,从服务器返回的值只包含两个可能的值:available和not available,因此,我们仅须检查这两个可能的值之一。相应代码如下所示:

function checkUsername_callBack(sResponseText)

{

var userValue = document.getElementById("username").value;

if (sResponseText == "available")

{

alert("The username " + userValue + " is available!");

}

else

{

alert("We’re sorry, but " + userValue + " is not available.");

}

}

如果服务器返回的响应是available,则该函数将告诉用户当前申请的用户名有效。否则如果返回的响应是not available,则该函数将告诉用户当前申请的用户名已经被占用。

检查电子邮件是否有效也可以采用类似的方法。checkEmail()函数用于获取用户在Email字段中输入的数据,并将该信息发送给服务器端的PHP程序。

function checkEmail()

{

var emailValue = document.getElementById("email").value;

if (emailValue == "")

{

alert("Please enter an email address to check!");

return;

}

var url = "formvalidator.php?email=" + emailValue;

var request = new HttpRequest(url, checkEmail_callBack);

request.send();

}

回调函数checkEmail_callBack()与checkUsername_callBack()函数的功能类似。在checkEmail_callBack()函数中采用了相同的程序逻辑,该函数将根据请求返回的信息告诉用户所输入的e-mail是否有效。

function checkEmail_callBack(sResponseText)

{

var emailValue = document.getElementById("email").value;

if (sResponseText == "available")

{

alert("The email " + emailValue + " is currently not in use!");

}

else

{

alert("I’m sorry, but " + emailValue + " is in use by another user.");

}

}

同样,在checkEmail_callBack()函数中,检查从服务器返回的响应是否是available,如果是,则通知用户他输入的e-mail可以使用。如果从服务器返回的响应是not available,则通知用户他输入的e-mail已经被其他用户注册。

使用XMLHttpRequest对象并不是唯一的解决办法,下面我们将介绍使用iframe方式来实现该表单的功能。