本篇文章讲解如何使用jQuery方便快捷的实现Ajax功能.统一所有开发人员使用Ajax的方式.
Ajax让用户页面丰富起来, 增强了用户体验. 使用Ajax是所有Web开发的必修课. 虽然Ajax技术并不复杂, 但是实现方式还是会因为每个开发人员的而有所差异.jQuery提供了一系列Ajax函数来帮助我们统一这种差异, 并且让调用Ajax更加简单.
51CTO推荐专题:jQuery从入门到精通 jQuery给力插件大阅兵
一. 原始Ajax与jQuery中的Ajax
首先通过实例, 来看一下jQuery实现Ajax有多简单. 下面是一个使用原始Ajax的示例:
上面的实例中, data/AjaxGetCityInfo.aspx?resultType=html 地址会返回一段HTML代码.
使用原始Ajax, 我们需要做较多的事情, 比如创建XmlHttpRequest对象, 判断请求状态, 编写回调函数等.
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>jQuery Ajax</title>
- <script type="text/javascript">
- $(function()
- {
- var xhr = new AjaxXmlHttpRequest();
- $("#btnAjaxOld").click(function(event)
- {
- var xhr = new AjaxXmlHttpRequest();
- xhr.onreadystatechange = function()
- {
- if (xhr.readyState == 4)
- {
- document.getElementById("divResult").innerHTML = xhr.responseText;
- }
- }
- xhr.open("GET", "data/AjaxGetCityInfo.aspx?resultType=html", true);
- xhr.send(null);
- });
- })
- //跨浏览器获取XmlHttpRequest对象
- function AjaxXmlHttpRequest()
- {
- var xmlHttp;
- try
- {
- // Firefox, Opera 8.0+, Safari
- xmlHttp = new XMLHttpRequest();
- }
- catch (e)
- {
- // Internet Explorer
- try
- {
- xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
- }
- catch (e)
- {
- try
- {
- xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
- }
- catch (e)
- {
- alert("您的浏览器不支持AJAX!");
- return false;
- }
- }
- }
- return xmlHttp;
- }
- </script>
- </head>
- <body>
- <button id="btnAjaxOld">原始Ajax调用</button><br />
- <br />
- <div id="divResult"></div>
- </body>
- </html>
而用jQuery的Load方法, 只需要一句话:
- $("#divResult").load("data/AjaxGetCityInfo.aspx", { "resultType": "html" });
曾经我是一个原始Ajax的绝对拥护者, 甚至摒弃微软的Asp.net Ajax, 因为我想要最高的代码灵活度. 使用原始Ajax让我感觉完成自己的工作更加轻松, 即使多写了一些代码. 但是当我去翻看别人的Ajax代码并且尝试修改的时候, 我改变了我的看法--我们的代码到处分布着创建XmlHttpRequest方法的函数, 或者某些Ajax程序逻辑性和结构性很差, 很难看懂.
我们可以将通用方法放到一个js文件中, 然后告诉大家"嘿伙伴们, 都来用这个js中的方法". 但是在某些时候有些新来的外包人员并不知道有这个js文件的存在. 而且其实这个通用的js就是一个公共的脚本类库, 我相信没有人会觉得自己开发一个类库会比jQuery更好!
所以我放弃了制造轮子的计划, 大家都使用jQuery编写Ajax相关的方法就可以解决各种差异性问题, 并且让工作更有效率.
现在只是用jQuery的Ajax函数, 我的页面变得简洁了:
二. jQuery Ajax详解
jQuery提供了几个用于发送Ajax请求的函数. 其中最核心也是最复杂的是jQuery.ajax( options ),所有的其他Ajax函数都是它的一个简化调用. 当我们想要完全控制Ajax时可以使用此结果, 否则还是使用简化方法如get, post, load等更加方便. 所以jQuery.ajax( options ) 方法放到最后一个介绍. 先来介绍最简单的load方法:
1. load( url, [data], [callback] )
Returns: jQuery包装集
说明:
load方法能够载入远程 HTML 文件代码并插入至 DOM 中。
默认使用 GET 方式, 如果传递了data参数则使用Post方式.
- 传递附加参数时自动转换为 POST 方式。jQuery 1.2 中,可以指定选择符,来筛选载入的 HTML 文档,DOM 中将仅插入筛选出的 HTML 代码。语法形如 "url #some > selector", 默认的选择器是"body>*".
讲解:
load是最简单的Ajax函数, 但是使用具有局限性:
1. 它主要用于直接返回HTML的Ajax接口
2. load是一个jQuery包装集方法,需要在jQuery包装集上调用,并且会将返回的HTML加载到对象中, 即使设置了回调函数也还是会加载.
不过不可否认load接口设计巧妙并且使用简单.下面通过示例来演示Load接口的使用:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>jQuery Ajax - Load</title>
- <script type="text/javascript" src="../scripts/jquery-1.3.2-vsdoc2.js"></script>
- <script type="text/javascript">
- $(function()
- {
- $("#btnAjaxGet").click(function(event)
- {
- //发送Get请求
- $("#divResult").load
- ("../data/AjaxGetMethod.aspx?param=btnAjaxGet_click" + "×tamp=" + (new Date()).getTime());
- });
- $("#btnAjaxPost").click(function(event)
- {
- //发送Post请求
- $("#divResult").load("../data/AjaxGetMethod.aspx", { "param": "btnAjaxPost_click" });
- });
- $("#btnAjaxCallBack").click(function(event)
- {
- //发送Post请求, 返回后执行回调函数.
- $("#divResult").load("../data/AjaxGetMethod.aspx", { "param": "btnAjaxCallBack_click" }, function(responseText, textStatus, XMLHttpRequest)
- {
- responseText = " Add in the CallBack Function! <br/>" + responseText
- $("#divResult").html(responseText); //或者: $(this).html(responseText);
- });
- });
- $("#btnAjaxFiltHtml").click(function(event)
- {
- //发送Get请求, 从结果中过滤掉 "鞍山" 这一项
- $("#divResult").load("../data/AjaxGetCityInfo.aspx?resultType=html" + "×tamp=" + (new Date()).getTime() + " ul>li:not(:contains('鞍山'))");
- });
- })
- </script>
- </head>
- <body>
- <button id="btnAjaxGet">使用Load执行Get请求</button><br />
- <button id="btnAjaxPost">使用Load执行Post请求</button><br />
- <button id="btnAjaxCallBack">使用带有回调函数的Load方法</button><br />
- <button id="btnAjaxFiltHtml">使用selector过滤返回的HTML内容</button>
- <br />
- <div id="divResult"></div>
- </body>
- </html>
上面的示例演示了如何使用Load方法.
提示:我们要时刻注意浏览器缓存, 当使用GET方式时要添加时间戳参数 (net Date()).getTime() 来保证每次发送的URL不同, 可以避免浏览器缓存.
提示: 当在url参数后面添加了一个空格, 比如" "的时候, 会出现"无法识别符号"的错误, 请求还是能正常发送. 但是无法加载HTML到DOM. 删除后问题解决.
2.jQuery.get( url, [data], [callback], [type] )
Returns: XMLHttpRequest
说明:
通过远程 HTTP GET 请求载入信息。
这是一个简单的 GET 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用 $.ajax。
讲解:
此函数发送Get请求, 参数可以直接在url中拼接, 比如:
- $.get("../data/AjaxGetMethod.aspx?param=btnAjaxGet_click");
- //或者通过data参数传递:
- $.get("../data/AjaxGetMethod.aspx", { "param": "btnAjaxGet2_click" });
两种方式效果相同, data参数会自动添加到请求的url中
如果url中的某个参数, 又通过data参数传递, 不会自动合并相同名称的参数.
回调函数的签名如下:
- function (data, textStatus) {
- // data could be xmlDoc, jsonObj, html, text, etc...
- this; // the options for this ajax request
- }
其中data是返回的数据, testStatus表示状态码, 可能是如下值:
"timeout","error","notmodified","success","parsererror"
在回调函数中的this是获取options对象的引用.有关options的各种说明, 请参见:
http://docs.jquery.com/Ajax/jQuery.ajax#options
type参数是指data数据的类型, 可能是下面的值:
"xml", "html", "script", "json", "jsonp", "text".
默认为"html".
jQuery.getJSON( url, [data], [callback] ) 方法就相当于 jQuery.get(url, [data],[callback], "json")
3. jQuery.getJSON( url, [data], [callback] )
Returns: XMLHttpRequest
相当于: jQuery.get(url, [data],[callback], "json")
说明:
通过 HTTP GET 请求载入 JSON 数据。
在 jQuery 1.2 中,您可以通过使用JSONP 形式的回调函数来加载其他网域的JSON数据,如 "myurl?callback=?"。jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。
注意:此行以后的代码将在这个回调函数执行前执行。
讲解:
getJSON函数仅仅将get函数的type参数设置为"JSON"而已. 在回调函数中获取的数据已经是按照JSON格式解析后的对象了:
- $.getJSON("../data/AjaxGetCityInfo.aspx", { "resultType": "json" }, function(data, textStatus)
- {
- alert(data.length);
- alert(data[0].CityName);
- });
服务器端返回的字符串如下:
[{""pkid"":""0997"",""ProvinceId"":""XJ"",""CityName"":""阿克苏"",""CityNameEn"":""Akesu"",""PostCode"":""843000"",""isHotCity"":false},
{""pkid"":""0412"",""ProvinceId"":""LN"",""CityName"":""鞍山"",""CityNameEn"":""Anshan"",""PostCode"":""114000"",""isHotCity"":false}]
示例中我返回的饿是一个数组, 使用data.length可以获取数组的元素个数, data[0]访问第一个元素, data[0].CityName访问第一个元素的CityName属性.
4.jQuery.getScript( url, [callback] )
Returns: XMLHttpRequest
相当于: jQuery.get(url, null, [callback], "script")
说明:
通过 HTTP GET 请求载入并执行一个 JavaScript 文件。
jQuery 1.2 版本之前,getScript 只能调用同域 JS 文件。 1.2中,您可以跨域调用 JavaScript 文件。注意:Safari 2 或更早的版本不能在全局作用域中同步执行脚本。如果通过 getScript 加入脚本,请加入延时函数。
讲解:
以前我使用dojo类库时官方默认的文件不支持跨域最后导致我放弃使用dojo(虽然在网上找到了可以跨域的版本, 但是感觉不够完美). 所以我特别对这个函数的核心实现和使用做了研究.
首先了解此函数的jQuery内部实现, 仍然使用get函数, jQuery所有的Ajax函数包括get最后都是用的是jQuery.ajax(), getScript将传入值为"script"的type参数, 最后在Ajax函数中对type为script的请求做了如下处理:
- var head = document.getElementsByTagName("head")[0];
- var script = document.createElement("script");
- script.src = s.url;
- //上面的代码动态建立了一个script语句块, 并且将其加入到head中:
- head.appendChild(script);
- //当脚本加载完毕后, 再从head中删除:
- // Handle Script loading
- if ( !jsonp ) {
- var done = false;
- // Attach handlers for all browsers
- script.onload = script.onreadystatechange = function(){
- if ( !done && (!this.readyState ||
- this.readyState == "loaded" || this.readyState == "complete") ) {
- done = true;
- success();
- complete();
- // Handle memory leak in IE
- script.onload = script.onreadystatechange = null;
- head.removeChild( script );
- }
- };
- }
我主要测试了此函数的跨域访问和多浏览器支持.下面是结果:
IE6 | FireFox | 注意事项 | |
非跨域引用js | 通过 | 通过 | 回调函数中的data和textStatus均可用 |
跨域引用js | 通过 | 通过 | 回调函数中的data和textStatus均为undifined |