Ajax는 웹 애플리케이션을 변화시키고 데스크톱 애플리케이션을 넘어서는 전례 없는 충격을 가져오고 있습니다. 그러나 모든 과장된 광고 뒤에는 ajax가 실제로 (X)HTML, Javascript 및 XML일 뿐이라는 사실을 깨달아야 합니다. 이 튜토리얼에서는 애플리케이션에 Ajax를 쉽게 추가하는 방법과 사용 방법을 알려 드리겠습니다. ajax 개발을 위한 인기 있는 자바스크립트 라이브러리 Jquey
1. ajax란 무엇입니까
이전에 ajax에 대해 들어본 적이 있거나 적어도 다음과 같은 ajax 애플리케이션을 사용해 본 적이 있을 것입니다. Gmail 간단히 말해서, ajax는 전체 페이지를 한 번에 다시 로드하는 대신 자바스크립트를 사용하여 데이터를 비동기적으로 처리합니다. 또한 SitePoint에 대한 Ajax 튜토리얼에 대한 좋은 소개가 있습니다. 이 단어는 Jesse James Garrett의 유명한 기사에서 유래되었습니다. 🎜>
안타깝게도 ajax에 대한 심층적인 실무 튜토리얼이 거의 없으며, ajax에서 사용하는 XMLHttpRequest 클래스는 웹 개발 초보자에게 매우 유용합니다. 그러나 다행스럽게도 많은 수의 javascript 라이브러리가 있습니다. 오늘 사용할 Jquery는 그 중 하나입니다.
Jquery는 물론 다른 라이브러리에는 없는 많은 기능을 제공하는 성숙한 Javascript 라이브러리이지만 크기가 19K라는 점은 인정해야 합니다. moo.fx처럼 3KB만큼 가볍지는 않습니다. 성능 및 기타 측면에 대한 비교 데이터를 볼 수 있습니다.
3. 사전 지식
이 튜토리얼을 따르려면 기본 자바스크립트가 필요합니다. 그러면 JavaScript를 빠르게 시작할 수 있습니다. 실제로 줄 끝의 중괄호, 함수 선언 및 선택적 세미콜론에 지나지 않습니다(Jquery의 경우 필수입니다). 또한, 웹 애플리케이션에 대해 이야기하고 있으므로 기본 HTML은 당연히 필수입니다.
4. Jquery 101
jQuery를 간단히 살펴보겠습니다. jQuery를 사용하려면 먼저 이 라이브러리를 다운로드해야 합니다. 다운로드 주소는 여기(현재 버전 1.1.2)입니다. jQuery의 구문은 매우 간단합니다. 요소의 경우 $()를 사용합니다. 이 기호는 document.getElementById()와 동일하지만 ID 지원 외에도 CSS 선택기와 일부 XPath 선택기를 지원하며 요소 배열을 반환할 수도 있습니다. $().
선택기를 작동하는 함수를 사용하고 싶습니다. 예를 들어 foo 클래스의 각 p에 "Hello World!"를 추가하고 색상을 빨간색으로 설정하려면 코드를 작성하면 됩니다. 다음과 같습니다:
$("p.foo").append("Hello World!").css("color","red")
일반적으로 매우 간단합니다. 이를 완료하려면 두 줄의 코드가 필요합니다.
코드는 다음과 같습니다.
jQuery 링크 메서드를 사용하면 다음을 작성할 수 있습니다. 객체가 필요하지 않은 jQuery 함수가 많이 있는데, 이는 독립적으로 작동한다는 의미입니다. 예를 들어, 우리가 사용할 post 함수는 The를 호출합니다. 메소드는 $.post(매개변수)입니다. 더 많은 jQuery 함수 정보는 온라인 문서 또는 Visualjquery.com에서 찾을 수 있습니다.
$("p.foo").append("Hello World!"); $("p.foo").css("color","red");
간단히 말해, 목록에서 두 가지 옵션을 무작위로 선택하고 이를 구문으로 결합해 보겠습니다. 이 예에서는 'Mashup', 'Folksonomy', 'Media'와 같은 web2.0 기능이 있는 단어를 사용하겠습니다. 등), 일반적으로 이러한 옵션은 텍스트 파일에서 가져옵니다. 사용자가 자바스크립트로 모든 조합(또는 최소한 모든 요소)을 다운로드하는 시간을 절약하기 위해 서버 측에서 신속하게 생성하고 jQuery를 사용하여 가져옵니다. jQuery는 JavaScript와 잘 작동하므로 코드에서 이를 사용하면 작업이 매우 쉬워집니다.
서버측 코드(php):
간단하게, 우리는 개념 생성기를 수행하기 위해 가장 간단한 코드를 사용합니다. 작동 방식에 대해 걱정하지 말고 그것이 수행하는 작업에 주의하십시오. 이 코드는 xml을 출력하지 않으며 단지 일반 텍스트를 입력한다는 점에 유의하십시오. 🎜>
코드는 다음과 같습니다.
<?php header("Cache-Control: no-cache"); // Ideally, you'd put these in a text file or a database. // Put an entry on each line of 'a.txt' and use $prefixes = file("a.txt"); // You can do the same with a separate file for $suffixes. $prefixes = array('Mashup','2.0','Tagging','Folksonomy'); $suffixes = array('Web','Push','Media','GUI'); // This selects a random element of each array on the fly echo $prefixes[rand(0,count($prefixes)-1)] . " is the new " . $suffixes[rand(0,count($prefixes)-1)]; // Example output: Tagging is the new Media ?>
这里,我们使用 Cache-Control 头选项是因为IE总是为同一个地址建立缓存,甚至页面内容有变化时也是.很明显,这对我们的例子很不利,因为我们在每次加载的时候重新生成一句话.我们也可以使用jQuery生成一个随机数加到地址的后边,不过这不像在服务器端这样处理比较简单.[译者著:其实作者在这里提供了ajax和IE cache冲突的两种解决方案.]
客户端代码(html)
可以开始编写前端代码了,然后我们就可以把ajax加进去了.我们需要做的仅仅是加一个按钮,好让用户点击一下获得一句新的语句,还有一个p标签,好让我们在从服务器端接收到语句的时候显示在p里面.我们将使用jQuery选中这个p以及加载返回的那句话,我们可以使用p的id来引用它.如果需要,你可以加载这句话到不同的元素标签中,这可能需要使用class了.不过这里,我们仅仅需要使用id就够了.此页面body标签中的内容为:
<input type="submit" id="generate" value="Generate!"> <p id="quote"></p>
一般说来,我们需要为这个按钮(就是这个id为generate的input)加上一个冗长的onSubmit 事件. 有时,我们用onSumit事件调用一个Javascript函数. 但是在jQuery里面,我们设置不需要修改任何html代码,我们可以简单的实现行为(事件处理)和结构(html代码)的分离.
客户端代码(jQuery)
终于该使用jQuery把我们的后台和前台结合到一起了.前面我提到我们可以使用jQuery从DOM中选择元素.首先,我们应该ixuanze这个按钮,并给它一个onClick事件响应.在这个事件代码中,我们可以选中p并且载入内容.下面是click事件响应的写法:
$("element expression").click(function(){ // Code goes here });
可能你已经知道,在CSS里选择一个元素的时候我们使用#来使用元素的id属性. 你可以在jQuery里使用同样的语法.因此,要选择那个按钮,我们可以使用#generate. 注意,这种语法可以让我们把事件处理函数定义成匿名的.
Mark Wubben's JavaScript Terminology page 提供了详细的关于匿名函数的解释,有兴趣可以参考.
我们将要使用jQuery中一个比较高级的ajax函数:load(). 假设我们的代码保存为script.php.我们这样把它和我们的客户端整合起来:
$("#generate").click(function(){ $("#quote").load("script.php"); });
只有:3行代码!现在我们已经做了一个完整的ajax随机语句生成器了!不错!
问题是javascript代码并不是在一个浏览器加载完就执行的函数内.这样的话,这段代码就会试图去关联一个可能还没有被加载的元素.一般情况下我们使用window.load来处理这个问题,不过这种方法的局限性在于,window.load只在所有的东西(图片及其它)被加载完成后加载一次.我们对等待这些图片的加载可能毫无兴趣--我们只是需要去获得DOM中的元素罢了.
幸运的是,jQuery有一个 $(document).ready()函数,如其名,它在DOM被加载完之后就被执行.
完整的代码
下面是完整的代码,使用 $(document).ready()以及一些简单的html和css:
代码如下:
<html> <head> <title>Ajax with jQuery Example</title> <script type="text/JavaScript" src="jquery.js"></script> <script type="text/JavaScript"> $(document).ready(function(){ $("#generate").click(function(){ $("#quote p").load("script.php"); }); }); </script> <style type="text/css"> #wrapper { width: 240px; height: 80px; margin: auto; padding: 10px; margin-top: 10px; border: 1px solid black; text-align: center; } </style> </head> <body> <p id="wrapper"> <p id="quote"><p> </p></p> <input type="submit" id="generate" value="Generate!"> </p> </body> </html>
代码可以在这里下载,注意你的jquery需要保存在php文件的同目录,并且名为 jquery.js .现在你已经熟悉jQuery了,让我们做些更复杂的:表单元素和XML处理,这才是真正的ajax!
示例二: 使用jQuery建造聊天程序
为了展示jQuery的强大,我们将建立一个具有ajax功能的聊天程序.它允许用户发布信息,并且可以实时的更新信息--但是没有任何的页面刷新.鉴于我们将要处理一个相对比较复杂的应用,我将更加深入的讲解jQuery的特性,向您展示她那些用起来很顺手的函数.
首先,我们来规划一下这个应用.我们不需要太多东西--一个前端,一个后端,一个jQuery的库就够了.但是,将会有一些代码处理前端和后端的结合,所以我们首先应该知道预期从系统里看到什么.
规划服务器端
此应用的后端需要处理信息的提交以及输出.把这个铭记在心,这样我们就可以为后端代码构建一个草图:
链接数据库
如果有信息提交
把信息插入到数据库
删除老的信息
从数据库获取信息并以XML显示 正如你所看到的,它很简单并且直白.如果你需要使用另外的语言来实现后端程序,你就可以使用这个规划来指导你.
规划客户端
前端需要使用ajax处理反馈,就像我们在第一个例子中做的那样.它需要处理信息的提交,并且用最新的消息不间断的更新聊天窗体.然而,我们将要用到另一个特性--我们将使用the current UNIX timestamp来展示那个消息被加载了,并且只是抓取这个信息,由此减少贷款使用以及服务器负载.下面就是客户端规划的草图:
页面加载的时候
设置当前的timestamp为0 (所有的信息都在此之后提交, 比如,所有的信息都会被获取)
调用函数获取消息
function(函数): 获取新消息
使用POST向服务其发送请求
调用函数处理XML响应
增加一个定时器并且每秒钟调用一次此函数(服务器的性能好的话可以提高此频率)
function: 转换新消息的XML
根据XML中的内容设定当前的timestamp
如果状态是 '2',则表示没有新消息,终止函数调用
否则,对反馈回来的每个消息进行处理, 以下面的格式加到聊天窗口的最上端:
提交信息的时候:
使用 POST向服务器发送请求, 需要指定:
作者姓名(用户指定)
消息体(用户指定)
标识这是一个post请求
最后一次向服务器请求的timestamp
保持输入文本框为空,便于用户在此输入信息
调用处理XML响应的函数 (以便让信息实时呈现出来)
看上去比服务器端有点复杂了,但是庆幸有了jQuery,代码不会很长.
规划数据库
我们将使用MySql数据库来存储信息(虽然任何sql数据库都能胜任此工作,并且代码相差也不是很大). 我们需要一个表,有四个列:消息id, 消息作者名,消息体,以及一个数字时间戳(timestamp). 下面使我们创建这个表的sql代码:
CREATE TABLE `messages` ( `id` int(7) NOT NULL auto_increment, `user` varchar(255) NOT NULL, `msg` text NOT NULL, `time` int(9) NOT NULL, PRIMARY KEY (`id`) );
由于我们不能判断到底消息有多长,我们现在就只使用一个text字段.
服务器端代码(XML)
要建立后端,我们首先应该知道我们需要后端输出什么(来决定前端和后端的接口),由此向后工作, 下面是一个简单的XML结构:
<?xml version="1.0"?> <response> <status>1</status> <time>1170323512</time> <message> <author>John Citizen</author> <text>Hello world!</text> </message> <message> <author>John Citizen</author> <text>Hello world again!</text> </message> </response>
注意我们已经增加一个标签'status', 它的值为1. 就如我上面提到的,一个状态值为1则标示新信息请求成功,2则表示请求成功但是没有新信息. 每个消息的实例都包括作者以及其信息.
服务器端代码(php)
现在,回到服务器端.我们将使用php来实现,不过由于输出的是xml,所以你可以使用你喜欢的任何语言来写后段代码,比如Perl或者asp.我们先定义一些配置信息这样便于我们以后对其进行修改. 我们需要数据库连接的具体信息,我们要存储的消息的数目(数据库可以处理成千上万行数据,所以这个可以适当的设大点),以及用户进到聊天室的时候消息显示的数目. 代码如下:
$dbhost = "localhot"; $dbuser = "root"; $dbpass = ""; $dbname = "chat"; $store_num = 10; $display_num = 10;
现在言归正传,我们继续看后端本身.数据库连接自然是必须的, 但是我们同时需要确认不让IE缓存请求数据,并且需要确认输出格式为XML.为了能够监视所有的错误,我们设置错误汇报为"所有错误"("all errors").为容易操作请求数据,我们为请求中的每个参数设置一个变量,每个变量将把请求中的参数值作为其自己的值. 代码如下:
error_reporting(E_ALL); header("Content-type: text/xml"); header("Cache-Control: no-cache"); $dbconn = mysql_connect($dbhost,$dbuser,$dbpass); mysql_select_db($dbname,$dbconn); foreach($_POST as $key => $value) $$key = mysql_real_escape_string($value, $dbconn);
foreach语句遍历所有的POST数据,并且为每个参数创建一个变量,并且给它赋值(比如path/to/file.php?variable=value将给$variable 赋值为"value").这样就简化了处理请求数据的过程,无需我们手动设定.
下面,我们将进入主要函数部分.现在我们处理消息向数据库的写入,以及根据设定的显示数目$display_num来从数据库中获取相应数目的消息. 当我们规划客户端的时候我提到过当提交消息的时候我们需要设定一个响应状态. 我们现在需要检查这个响应--我们给蚕食'action'赋值'postmsg',表示我们正在处理这个检查并且插入新数据到数据库.处理的时候我们需要插入新的unix时间戳( timestamp).
然而,我们仍然需要清理我们的数据库.根据你的数据库的限制,你可以设定存储数据的数量.一般而言,不赞成使用消息日志,所以我这里设定默认存储10条消息.我们将使用一个函数来获取最新消息的id,并且决定是否删除.举例来说,如果我们增加第11个消息,我们使用11减去存储量(10)就得到一个id阈值(现在是1),这样的话我们就可以删除小于等于这个阈值的所有消息,这个例子终究是删除第一条消息.有了sql,我们可以只写一条语句就处理这些.
下面的代码片段检查 'postmsg'响应,向数据库添加数据,以及清理数据库.
if(@$action == "postmsg") { mysql_query("INSERT INTO messages (`user`,`msg`,`time`) VALUES ('$name','$message',".time().")"); mysql_query("DELETE FROM messages WHERE id <= ". (mysql_insert_id($dbconn)-$store_num),$dbconn); }
使用其他服务器端技术的开发者可以写出等价的代码.注意我们使用time函数来获取unix时间戳.我们可以假设在sql执行过程中这个时间不会改变(即便是很慢的服务器,这段代码也可以每秒钟执行几百次).所以当我们向客户端返回一个时间戳的时候,我们可以简单的再次调用time函数,这个值也是可信的.
剩下的工作就是要处理从数据库获取最新的消息并且以XML的形式输出.这里就要用到我上面写的那段xml代码了.然而,大部分代码是sql,我们使用sql的强大来处理这个工作,代码的执行时间不受影响. 下面是sql查询的要求:
它只是获取作者以及信息
它只是获取还没有被下载的信息--客户端有一个最后请求的时间戳,因此这个时间戳可以被插入到sql中
需要对消息进行排序一遍让最新的消息排在最后,并且允许逆序显示.
根据配置信息限制获取的消息数量.
任何熟悉sql的人都不会反对这很简单.剩下的就是这些代码了.先看看查询语句:
$messages = mysql_query("SELECT user,msg FROM messages WHERE time>$time ORDER BY id ASC LIMIT $display_num",$dbconn);
剩下的代码就相当基础,如果没有结果,就设置状态代码为0,否则,设置为1,输出最初的xml,每个消息的xml以及最终的xml.就是这些了,代码如下:
if(mysql_num_rows($messages) == 0) $status_code = 2; else $status_code = 1; echo "<?xml version="1.0"?>n"; echo "<response>n"; echo "t<status>$status_code</status>n"; echo "t<time>".time()."</time>n"; while($message = mysql_fetch_array($messages)) { echo "t<message>n"; echo "tt<author>$message[user]</author>n"; echo "tt<text>$message[msg]</text>n"; echo "t</message>n"; } echo "</response>";
最终的代码在压缩包里,所以不需要复制上面的代码.现在后端程序完成了,下面我们就该更有趣的工作了--使用html和jQuery!
客户端代码(html)
在使用jQuery之前,我们先处理一下html的页面.这样的话,当我们必须确定使用那些元素来获取或者更新使用jQuery返回的数据时,我们就知道怎么做了.我们不需要很多东西:一个外围p,一个消息段落以及一个有用户名和消息文本框的form,还有一个submit按钮.最后还需要加一个加载信息时的提示--我们可以使用jQuery轻松的移除它.下面就是代码:
代码如下:
<p id="wrapper"> <p id="messagewindow"><span id="loading">Loading...</span></p> <form id="chatform"> Name: <input type="text" id="author" /> Message: <input type="text" id="msg" /> <input type="submit" value="ok" /><br /> </form> </p>
客户端代码(jQuery)
现在,我们继续看jQuery在客户端的使用。首先,我们需要生命当前消息的时间戳为0,并且在服务器端调用函数来加载消息:
timestamp = 0; updateMsg();
然后,我们将完成表单提交的代码。jQuery允许我们为表单的submit事件添加一个事件钩子,就像在html代码中直接写onSubmit事件的效果一样,但是不需要动任何html代码。下面是submit事件:
$("form#chatform").submit(function(){ /* Code */ });
这里我们用CSS选择符语法来引用到一个id为'chatform'的表单元素,一旦我们进入表单提交的代码,我们可以使用jQuery的$.post来发送一个POST请求.在$.post的调用中,我们可以使用表单元素的id来选择它的值,就像我们先前演示的那样.知道了这些,让我们看一下我们的ajax调用:
$.post("backend.php",{ message: $("#msg").val(), name: $("#author").val(), action: "postmsg", time: timestamp }, function(xml) {
注意这里传过去的参数数组是以大括号括起来的.如果你有多个参数的话,可以简单的以逗号分割,并且使用JSON格式,像上面演示的那样.由还可以使用jquery的ajax函数发送一个get请求,会有一个json风格的响应,可以使用jQuery把反馈的文本转换成更容易阅读的形式.要记住,这种方式只有对get请求类型才起作用,对我们这里使用的post则无效.因此,我们这里将使用最简单的XML.
现在,我们看一下XML响应.为代码重用,我们在这里为处理xml创建一个函数并且调用它:
addMessages(xml);
我们将在后边实现它,以便我们现在专注实现表单提交代码.我们现在写出来的代码就是$.post需要的全部了,因此我们加个大括号以及一个返回false的提示(return false; ).这行将使标准浏览器提交表单错误代码的时候失效.浏览器并不把请求发送到另一个页面--因为我们已经处理了事件提交,不需要由浏览器来处理了.这既是代码的全部:
代码如下:
$("form#chatform").submit(function(){ $.post("backend.php",{ message: $("#msg").val(), name: $("#author").val(), action: "postmsg", time: timestamp }, function(xml) { addMessages(xml); }); return false; });
现在让我们回头看看addMessages()函数,来处理xml响应信息.使用jQuery的DOM操作以及遍历函数使它的实现变得很简单. 记得我曾经提到的状态代码么?现在我们该看看怎么处理它了:
if($("status",xml).text() == "2") return;
我还没有提过jQuery的相关上下文.这里函数调用的xml告诉jQuery不要区在html文档中找,而应在服务器端发送给我们的xml文件中.
这行代码检查状态代码为2,则表示完成了一次成功的请求但是没有新信息添加到窗体中去.return关键字终止函数调用.然后我们设置为xml的时间戳设值.
timestamp = $("time",xml).text();
再次,我们从xml的time标签获得值.
现在,我们继续看jQuery遍历数组的函数:each(); jQuery有一个遍历数组的有趣方法.我们使用一个标准的选择符声明,并且each()函数传递一个参数--一个函数处理相匹配元素的每一个实例. 在我们的示例中,元素就是服务器端返回的每一个
$("message",xml).each(function(id) { message = $("message",xml).get(id);
我们然后就可以使用jQuery的$函数来获取message的值.既然我们得到了我们需要的所有数据,我们就应该把它加到消息显示区里面去.这个消息显示窗体有一个叫做'messagewindow'的id,因此我们使用$("#messagewindow")来选择到它并且使用prepend()来添加我们的数据:
$("#messagewindow").prepend("<b>"+$("author",message).text()+ "</b>: "+$("text",message).text()+ "<br />");
就是这些了,把他们放在一起,现在我们的函数就是:
代码如下:
function addMessages(xml) { if($("status",xml).text() == "2") return; timestamp = $("time",xml).text(); $("message",xml).each(function(id) { message = $("message",xml).get(id); $("#messagewindow").prepend(""+$("author",message).text()+ ": "+$("text",message).text()+ "
"); }); }
最后,我们需要来实现我们在代码开始调用的函数updateMsg, 这个函数要到服务器查询新信息,并且调用上面的addMessages来响应.同时需要设置一个超时时间,好让聊天窗口自动更新. 要开始做这些,我们只需要向服务器提交一个时间戳,引起这个$.post调用如下:
$.post("backend.php",{ time: timestamp }, function(xml) {
我上面提到,我们需要在这时移除我们的loading消息,因此,我们在这个span上调用remove函数:
$("#loading").remove();
然后,我们在xml对象中收到xml响应,把它传递给我们的addMessages 函数:
addMessages(xml);
最后我们调用javascript的setTimeOut()函数,来间断执行代码.这就是完整的代码:
function updateMsg() { $.post("backend.php",{ time: timestamp }, function(xml) { $("#loading").remove(); addMessages(xml); }); setTimeout('updateMsg()', 4000); }
整合代码
现在我们把所有的代码整合到一起.代码可以在这里下载( this downloadable zip file).不过,请看这里,我们加了一些html和css到我们的程序中:
代码如下:
你看到了,仅仅使用22行javascript代码,8行html以及大约50行php,我们就实现了一个完整的基于ajax的web聊天室应用程序.试一下吧,然后加入到你自己的网站上.创建你自己的ajax程序,使用这里的技术,或者你有自己的好点子.用这里的代码去做电信东西.如果你觉得使用xml很不爽,那你可以直接在你的应用程序中生成html,然后使用load来加载到客户端.如果你想的话,可以试试用功能强大的xml标签属性以及jQuery的attr()函数. 现在你应该已经很惊讶于用jQuery实现ajax的简单了吧!
[全文完]