首页 » JavaScript » Ajax

Ajax应用出现在2005年,Google的Jesse James Garret在他的文章中提出了这个词汇。在Garret的文章发表前,Ajax所基于的XMLHttpRequest对象在IE和Netscape/Mozilla等浏览器中已存在了约4年时间,但没引起太大关注。2004年,当Google使用XMLHttpRequest发布其Gmail Web邮件应用程序,以及Garret的文章发表后,人们对Ajax的兴趣如洪水般爆发。

Ajax不是新技术,而是HTML、Javascript、CSS、XML、DOM、HTTP,以及服务端等多种技术的综合。Ajax最显著的特点是:在不用刷新整个页面的前提下更新网页的部分内容。Ajax中的A表示异步(Asynchronous),ja表示Javascript,x表示XML。但实际应用中,数据格式未必是XML,可以是纯文本(字符串)、JSON等其他格式。

Ajax节省了网络流量,加载页面也许需要几十k流量,但Ajax只需要几百字节,更重要的是,Ajax提高了响应速度,改善了用户体验。

XMLHttpRequest对象

XMLHttpRequest对象是理解Ajax的核心,是客户端(通常是浏览器)和服务器间交互的通道。

属性 说明
onreadystatechange 当readyState属性发生变化时的回调函数
readyState 请求的状态。0: 未初始化,1: 正在载入,2: 已载入, 3: 交互,4: 已完成
responseText 以字符串形式返回的数据
responseXML 以XML格式返回的数据
status 服务器返回的状态码,如200
statusText 服务器返回的状态码字符串,如OK

XMLHttpRequest对象的方法

open('method', 'url', asynchronous)
method指定HTTP请求的方法(可以是GET, POST, HEAD),目标是url,最后一个参数表明是否以异步方式请求,值为true/false。
send(content)
以POST方式发送该请求,参数可选。

其他方法包括:abort()getAllResponseHeaders()getResponseHeader(header)setRequestHeader('x', 'y')

XMLHttpRequest对象简单使用

  1. 创建1个XMLHttpRequest对象。
  2. 为XMLHttpRequest对象的onreadystatechange属性赋予一个回调函数。
    1. 回调函数表明当服务器端响应时的处理。
    2. 回调函数内部检测readyStatestatus的值,查看请求/响应是否成功。成功状态下readyState4status200
  3. 调用open()send()方法发送请求。

因为是异步调用,所以在发送请求前需要注册回调函数。

示例代码

初学Ajax时写的一段代码:利用Ajax从服务器获取随机数。

客户端(JS代码)

function get_ajax()
{
    var xml_http;
    try {
        xml_http = new XMLHttpRequest();
    } catch(e) {
        xml_http = new ActiveXObject("Msxml2.XMLHTTP");
    }

    xml_http.onreadystatechange=function() {
        if(xml_http.readyState == 4 && xml_http.status == 200) {
            document.getElementById("rand").innerHTML = xml_http.responseText;
        }
    }
    xml_http.open("GET", "learn-ajax.php", true);
    xml_http.send(null);

    var t = setTimeout("get_ajax()", 1000);
}

首先是创建XMLHttpRequest对象,用new XMLHttpRequest()即可,为了在IE下能工作,可能需要调用MS特有的XMLHttpRequest对象:new ActiveXObject("Msxml2.XMLHTTP")new ActiveXObject(Microsoft.XMLHTTP)(更古老的方式)。

然后再注册回调函数,以及编写回调函数(将服务器返回的字符串,更新于rand这个id)。

再是发送HTTP请求。

最后,为了让程序循环,用setTimeout()设置超时,超时后调用自己。

另外,需要在HTML的body标签处添加onload="get_ajax()",在body标签之后添加如span id="rand"这样的标签即可。

服务器端(PHP代码)

<?php
$r = rand();
echo $r;
?>

为了避免缓存造成更新不及时的影响,可以通过多种方法禁用缓存:

<?php
header("Content-Type: text/plain");
header("Expires: 0");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
/* for IE */
header("Cache-Control: post-check=0, pre-check=0", false);
/* for HTTP/1.0 */
header("Pragma: no-cache");
$r = rand();
echo $r;
?>

参考:客户端完整代码服务器端完整代码

jQuery中的Ajax

jQuery有对Ajax的封装。 $.ajax()发起异步HTTP请求,是AJAX的底层封装,用户可以用$.get()等高级API。 $.ajax()返回值是jqXHR对象。jqXHR是浏览器原生XMLHttpRequest对象的超集,它包含responseText, responseXML属性,以及getResponseHeader()方法等。可以用jqXHR.done(), jqXHR.fail(), jqXHR.always()绑定回调函数(jqXHR.success(), jqXHR.error(), jqXHR.complete()等方法已不提倡)。

例如注册新用户时检查用户名是否存在:

$("#username").blur(function(){
        $.ajax({
            url: "user_exists.php?username=" + $("#username").val();
            }).done(function(msg){
                alert(msg);
                });
        });

$.ajax()

$.ajax()是$.get()、$.post()的根本,其函数原型为:

$.ajax(url [,settings]);

其中settings是一个JS对象,常见的设置项包括:

设置项说明
async是否异步执行,默认为true。可置为false,表示同步执行。
type默认为"GET",和设置为"POST"。

$.post()

$.post()函数原型:

$.post(url [,data] [,success(data, textStatus, jqXHR)] [,dataType]);

$.post()是对$.ajax()的简单封装:

$.ajax({
    type: "POST",
    ...     /* 其他参数依次赋值 */
});

简单的提交数据:

$.post("/login.php", { name:"berlinix", password:"MY-PASS" });

提交一个表单数据,先序列化:

$.post("/login.php", $("#loginform").serialize());

其他

Ajax的问题

《Javascript权威指南 5/e》20.3.4关于Ajax的警告中,列举了3个Ajax的主要问题。

1. Ajax本身没有提供可视化反馈。传统链接,用户点击,浏览器加载,并让用户知道浏览器在加载新页面;但Ajax本身是悄悄进行的,作者建议对基于Ajax的应用,在等待XMLHttpRequest响应时,提供某种可视化反馈(如简单的DHTML动画)。

2. Ajax使用HTTP脚本载入和显示新内容时,URL没有发生改变,则用户不能把新页面加入书签,也不能从浏览器地址栏获取页面的URL,典型的如地图页面,缩放或移动位置,URL并不改变。作者建议学习Google Maps的方案,即在页面包括一个"link to this page"的链接,在一个URL中封装应用程序状态,并在URL需要的时候,提供给用户使用。

3. Ajax脚本可以绕开浏览器的历史机制,用户通过浏览器的后退/前进,无法显示由Ajax生成的新页面。作者建议Ajax应用提供自己的撤销/恢复选项,并不要和浏览器的后退/前进混淆。

Web Sockets

Web Sockets是建立于客户端/浏览器与服务器间的双工通道,服务器可以主动推送消息给浏览器。Web Sockets相比Ajax,有更低的时延,更小的网络带宽占用,响应速度更快。

分享

0