11.3.7 教程:使用get()函数
在本教程中,我们将使用Ajax提交来自一个登录表单的信息。当访问者提供了正确的用户名和密码时,将出现一条消息告诉他已经成功登录,如果登录信息不正确,将在同一页面上出现一条错误消息,而不会载入一个新的Web页面。
注意:为了成功地完成本教程,我们需要有一个运行的Web服务器来测试页面。参见本章中的“快速熟悉:安装一个Web服务器”部分关于如何在计算机上安装一个测试服务器的介绍。
概览
我们将从图11-8所示的表单开始。它包含了提供登录到服务器的用户名和密码的字段。当表单提交的时候,服务器试图验证用户存在并且密码正确。如果提供的信息和有效的登录身份相符,那么,服务器将允许该访问者登录。
高级用户提示接收来自服务器的XML
XML是计算机之间交换数据的一种常用格式。和HTML一样,XML允许我们使用标签来区别信息。和HTML不同的是,我们可以自由地提出准确地反映数据的内容的标签。例如,一个简单的XML文件可能如下所示:
<?xml version="1.0"?>
<message id="234">
<from>Bob</from>
<to>Janette</to>
<subject>Hi Janette</subject>
<content>Janette, let's grab lunch
to-day.</content>
</message>
正如你所看到的,这里有一个名为<message>的主标签(叫做根元素),等同于H T M L的<html>标签,还有定义了每段数据的含义的其他几个标签。
在使用Ajax的时候,我们可以有一个返回XML文件的服务器程序。jQuery从一个XML文件读取和提取信息都没有问题。当使用get()或post()函数的时候,如果服务器返回一个XML文件,发送给回调函数的那个data参数将包含XML文件的DOM。换句话说,jQuery将会读取XML文件并且将其当做另一个文档对待。然后,我们可以使用jQuery的选择器工具来访问XML中的数据。
例如,假设一个名为x m l.p h p的服务器端文件返回上面列出的XM L,并且我们想要获取<content>标签内的文本。XML文件变成了返回数据,因此,回调函数可以处理它。我们可以使用jQuery find()函数,并且使用经常和jQuery一起使用的任何常规选择器,来查找该X ML以找到一个特定的CSS元素。例如,可以找到一个元素、类、ID或者子孙选择器(参见4.6.2节),或者jQuery的过滤器(参见4.6.3节)。例如:
$.get('xml.php','id=234’,processXML);
function processXML(data){
var messageContent=$(data).
find('content').text();
}
这里的关键是$(data).find('content'),它告诉jQuery选择data变量中的每个<content>标签。因此,在这个例子中,data变量包含了返回的XML文件,这段代码告诉jQuery查找XML中的<content>标签。
要了解有关X M L的更多内容,请访问w w w.w3schools.com/XML。如果想要获取关于如何从一个服务器生成XML的一些信息,可以查看www.w3schools.com/XML/xml_server.asp。如果想要阅读有关jQuery的find()函数的内容,可以在http://docs.jquery.com/Traversing/find#expr找到更多信息。
图 11-8 一个基本的登录页面总是简单的事情:只是几个字段和一个提交按钮。然而,当用户登录的时候,真的没有理由离开该页面。通过添加Ajax,我们可以提交访问者的身份,然后,通知他是否成功登录
我们将通过一个XMLHttpRequest来发送登录信息,从而给页面增加Ajax。服务器将会给回调函数发送一条消息,如果登录信息有效,它会删除表单并且显示一条“logged in”消息,或者如果登录无效,将显示一条错误消息。
编程
参见1.3节中的“注意”部分了解如何下载教程文件。最初的文件包含了HTML表单,准备好了供我们添加一些jQuery和Ajax编程。
1.在文本编辑器中打开chapter11文件夹下的文件login.html。
到jQuery库文件的链接以及$(document).ready()函数已经准备好了。首先选择该表单并为其添加一个submit事件。
2.单击$(document).ready()函数内的空行并输入:
$('#login').submit(function(){
});//end submit
这个<form>标签有一个ID为login,因此jQuery选择器$('#login')选择了该表单,而submit()函数给submit事件添加了一个事件处理程序。换句话说,当访问者试图提交表单时,我们打算创建的函数将会运行。
下一步是从表单收集信息并将其格式化为提交给服务器的一个查询字符串。我们可以通过如下步骤做到这点:找到每个表单字段,提取访问者已经录入的信息,然后通过连接这些不同的信息片段来构建查询字符串。幸运的是,jQuery的serialize()函数一次性负责所有这些细节。
3.按下回车键以创建一个空行,并输入:
var formData=$(this).serialize();
这行代码首先创建了一个变量来存储表单数据,然后对表单应用了serialize()函数。别忘了,$(this)引用当前的元素,因此,在这个例子中,它引用了登录表单,和$('#login')是相同的(参见4.9.2节了解$(this)是如何工作的)。serialize()函数(参见11.3.5节的“jQuery的serialize()函数”部分)接收一个表单,提取字段名和值,并将它们组合为合适的格式以提交给服务器。
现在使用post()函数来设置XMLHttpRequest。
4.按下回车键并创建另一个空行,并输入:
$.get('login.php',formData, processData);
这行代码给post()函数传递了3个参数。第一个参数'login.php'是一个字符串,表明了数据应该发送到哪里,在这个例子中,是发送给服务器上一个名为login.php的文件。第二个参数是包含了发送给服务器的数据的查询字符串,即登录信息。第三个参数processData引用了将要处理服务器响应的回调函数。我们现在来创建该函数。
5.在上一行的后面添加另外一个空行并输入:
1 function processData(data){
2
3}//end processData
这些代码行构成了回调函数的外壳,其中还没有程序。注意,这个函数设置来接收将会是来自服务器的响应的一个参数(data)。服务器端页面通过编程来返回一个单个的单词,如果登录成功的话是pass,如果登录失败的话是fail。
换句话说,根据来自服务器的响应,脚本要么显示出消息让访问者知道他成功地登录了,或者他没有成功登录,这是使用条件语句的理想的地方。
注意:本教程中使用的服务器端页面不是一个完备的登录脚本。如果提供了正确的身份,它确实能够响应,但是,它不能真正地用来对一个站点进行密码保护。有很多种方式可以对一个站点进行有效的密码保护,但是大多需要设置一个数据库或者需要针对Web服务器设置各种配置选项,这些步骤都超出了这个基本的教程的讨论范围。要使用一个真正的、基于PHP的而且使用了jQuery的登录脚本,请访问http://www.html-form-guide.com/php-form/php-login-form.html。位于http://www.youtube.com/watch?v=4oSCuEtxRK8的YouTube视频也说明了如何编写必需的PHP。
6.在processData()函数中(换句话说,在步骤5的第2行中)输入:
1 if(data=='pass'){
2$('#content').html('<p>You have successfully logged on!</p>');
3}
这里的第1行检查从服务器返回的信息是否是字符串'pass'。如果是,登录就成功了,并且显示一条成功消息(见第2行)。表单位于ID为content的<div>标签中,因此$('#content').html('<p>You have successfully logged on!</p>')将用一个新的文本段替换<div>中的内容。换句话说,这个表单消失,并且登录成功的消息将会在该位置显示。
要完成任务,我们将添加一个else子句,如果访问者没有提交正确的登录信息,将告知他。
7.给processData()函数添加一个else子句,使其看上去如下所示(添加的代码部分用粗体显示):
1 function processData(data){
2 if(data=='pass'){
3$('#content').html('<p>You have successfully logged on!</p>');
4}else{
5$('#formwrapper').prepend('<p id="fail">Incorrect?
6 login information.Please try again</p>');
7}
8}//end processData
第5行显示了登录失败的消息。注意,这里使用了prepend()函数。正如本书4.7节所介绍的,prepend()允许在一个元素的开头添加内容。它不会删除已经有的内容,而只是添加更多的内容。在这个例子中,我们想要让表单留在该处,以便访问者可以再次尝试登录。
8.保存文件并在Web浏览器中预览。
要让这个教程工作,我们必须通过Web浏览器使用一个URL来预览这个页面,例如http://localhost/chapter11/login.html。参见本章中的“快速熟悉:安装一个Web服务器”部分了解如何安装Web服务器的更多信息。
9.尝试登录站点。
你可能会想:“但是稍等,你还没有给我用户名和密码!”这正是问题所在,当没有正确地登录的时候,看看会发生什么。再次尝试登录,将会看到“Incorrect login information”消息再次出现(如图11-9所示)。因为prepend()函数并没有删除第一条错误消息,它只是再次添加了该消息。这看上去根本不对。
有几种方法来处理这个问题。例如,在表单下插入一个空的div(<div id=“failMessage”>)。然后,当登录失效的时候,直接替换其HTML。然而,在这个例子中,页面上没有空的div标签。相反,使用一个基本的条件语句来检查是否已经存在错误消息,如果是,那么,没必要再次添加它。
图 11-9:jQuery的prepend()函数给已经存在的一个元素添加HTML。它不会删除任何内容,因此如果不小心,可能最终会重复添加同样的消息
10.添加另外一条语句(如下的第5行和第8行):
1 function processData(data){
2 if(data=='pass'){
3$('#content').html('<p>You have successfully logged on!</p>');
4}else{
5 if($('#fail').length==0){
6$('#formwrapper').prepend('<p id="fail">Incorrect?
7 login information.Please try again</p>');
8}
9}
10}//end processData
注意,错误消息段落有一个ID为fail,因此,我们可以使用jQuery来检查页面上是否存在该ID。如果它不存在,那么该程序会在页面上显示错误消息。检查一个元素是否已经存在于页面上的一种方法是尝试使用jQuery来选择它。然后可以检查结果的length属性。如果jQuery没有找到任何匹配的元素,length属性为0。换句话说,$('#fail')试图找到ID为fail的一个元素。如果jQuery不能找到它,换句话说,错误消息还没有显示到页面,那么length属性为0,条件语句将为true,并且程序显示错误消息。一旦错误消息出现在页面上了,条件语句结果总是false,并且错误消息不会再次出现。
最后,需要告诉Web浏览器不应该自己提交表单数据,我们已经使用Ajax提交了。11.在submit事件的末尾(如下的第15行)添加return false;。完成后的脚本如下所示:
1$(document).ready(function(){
2$('#login').submit(function(){
3 var formData=$(this).serialize();
4$.post('login.php',formData, processData);
5 function processData(data){
6 if(data=='pass'){
7$('#formwrapper').html('<p>You have successfully logged on!</p>');
8}else{
9 if(!$('#fail').length){
10$('#formwrapper').prepend('<p id="fail">Incorrect↵
11 login information.Please try again</p>');
12}
13}
14}//end processData
15 return false;
16});//end submit
17});//end ready
12.保存文件并再次预览该页面
尝试再次登录:用户名为007而密码为secret。本教程的一个完整版本complete_login.html位于chapter11文件夹下。
注意:如11.3.3节所介绍,尽管jQuery的post()和get()函数幕后的工作是完全相同的,但是jQuery还是必须执行两套不同的步骤来让Ajax请求正确地工作。可以通过把脚本中的post改为get(参见步骤11中的第4行)来自己检查这一点。本教程的服务器端脚本编写为可以接受GET或POST请求。