Higanbana

Ajax

Ajax全称为“Asynchronous Javascript and XML”(异步javascript和XML),它并不是指一种单一的技术,而是有机地利用了一系列交互式网页相关的技术所形成的结合体,它的出现结束了“单击,等待”的传统交互模式,开启了无刷新更新页面的新时代。

Ajax的优点

  1. 不需要插件支持
    ajax不需要任何浏览器插件,就可以被绝大多数的主流浏览器所支持,用户只需要允许javascript在浏览器上执行即可。
  2. 优秀的用户体验
    这是ajax技术的最大优点,能在不刷新整个页面的前提下更新数据,这使得web应用程序能更为迅速地回应用户的操作。
  3. 提高web程序的性能
    与传统模式相比,ajax模式在性能上的最大区别就在于传输数据的方式,在传统模式中,数据是通过提交表单来实现的,而数据获取是靠全页面刷新来重新获取整页的内容。ajax模式只是通过XMLHttpRequest对象向服务器提交希望提交的数据,即按需发送。
  4. 减轻服务器和带宽的负担
    ajax的工作原理相当于在用户和服务器之间加了一个中间层,使用户操作与服务器响应异步化。它在客户端创建ajax引擎,把传统方式下的一些服务器负担的工作转移到客户端,便于客户端资源来处理,减轻服务器和带宽的负担。

Ajax的缺点

  1. 破坏浏览器 “后退”按钮的正常功能
    在ajax中,“前进”和“后退”按钮的功能都会失效。用户经常会遇到这情况,当单击一个按钮触发一个ajax交互后,如果点击“后退”按钮,浏览器会直接后退到前一个页面,而不是仅仅是回退到ajax交互操作前。
  2. 需要处理浏览器兼容性问题

创建XMLHttpRequest对象

XMLHttpRequest对象简称XHR对象,它是ajax技术的核心,发送异步请求、接收响应及执行回调都是通过它来完成的。ie7+、firefox、opera、chrome和safari都支持原生的XHR对象,在这些现代浏览器中这样创建:

1
var xhr = new XMLHttpRequest();

在ie5和ie6中,是以ActiveXObject的方式引入XHR对象的:

1
var xhr=new ActiveXObject("Microsoft.XMLHTTP");

如果你既想支持现代浏览器又不想放弃ie5和ie6,那么你需要做一个逻辑判断:

1
2
3
4
5
6
var xhr
if(window.ActiveXObject){
xhr = new ActiveXObject("Microsoft.XMLHTTP")
}else if (window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}

XMLHttpRequest对象的属性

readyState

该属性表示请求/响应过程中的当前活动阶段。该属性可取的值如下:

  • 0:未初始化。尚未调用open()方法。
  • 1:启动。已经调用open()方法,但尚未调用send()方法。
  • 2:发送。已经调用send()方法,但尚未接收到响应。
  • 3:接收。已经接收到部分响应数据。
  • 4:已经接收到全部响应数据,而且已经可以在客户端使用了。

只要readyState属性的值发生变化,就会触发readystatechange事件,可以利用这个事件来检测每次变化后的readyState的值。通常我们只对readyState值为4的阶段感兴趣,因为这个时候所有的数据都已经就绪。

responseText

作为响应主体被返回的文本。无论内容类型是什么,响应主体的内容都会保存在这里,如果响应包含了为响应体指定字符编码的头部,就使用该编码。否则,假定使用 Unicode UTF-8。如果 readyState 小于 3,这个属性就是一个空字符串。当 readyState 为 3,这个属性返回目前已经接收的响应部分。如果 readyState 为 4,这个属性保存了完整的响应体。

responseXML

如果响应的内容类型是“text/xml”或“application/xml”,这个属性中将保存包含着响应数据的XML DOM文档。对于非XML数据而言,responseXML属性值将为null。

status

响应的http状态。检查status属性可以确定响应是否已成功返回(在readyState>3时才可以读取)。

  • http状态码200是响应成功返回的标志,此时responseText属性的内容已经就绪,而且在内容类型正确的情况下(XML类型),responseXML属性也能够访问了。
  • http状态码304表示请求的资源没有被修改,可以直接使用浏览器中缓存的版本,当然也意味着响应式有效的。
  • http状态码404表示请求错误。
    ······

statusText

http状态的说明。比如在状态码为200时,statusText的值为“OK”。

XMLHttpRequest对象的方法

open()

在使用XHR对象时,要调用的第一个方法是open(),它接受三个参数:

  1. 要发送的请求类型,如“get”“post”等。
  2. 请求要访问的URL。
  3. 选择同步或异步的布尔值。true表执行异步操作,false表示同步。
    • 同步:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求。
    • 异步:客户端发出一个请求后,无需等待服务器响应结束后,就能发出第二个请求。

send()

send方法接收一个参数,将被写入到请求报文里面传递,即要做为请求主体发送的数据。调用send()之后,请求就会被分派到服务器。

  • 如果不需要通过请求主体发送数据,比如请求类型是“get”时,参数是直接写到url里面,则必须传入null,因为这个参数对于某些浏览器来说是必须的。
  • 请求类型是“post”时,请求参数需要写入到send方法里。

abort()

调用这个方法后,XHR对象会停止触发事件,而且也不再允许访问与响应有关的对象属性。

http头部信息

默认情况下,在发送XHR请求的同时,还会发送头部信息,虽然不同的浏览器实际发送的头部信息会有所不同,但是基本上是所有浏览器都会发送的有以下这些:

  • Accept:浏览器能够处理的内容类型。
  • Accept-Charset:浏览器能够显示的字符集。
  • Accept-Encoding:浏览器能够处理的压缩编码。
  • Accept-Language:浏览器当前设置的语言。
  • Connection:浏览器与服务器之间连接的类型。
  • Cookie:当前页面设置的任何Cookie。
  • Host:发出请求的页面所在的域。
  • Referer:发出请求的页面的URI。
  • User-Agent:浏览器用户代理字符串。

getResponseHeader()

这个方法可以设置自定义的请求头部信息,它接收两个参数:

  1. 头部字段的名称
  2. 头部字段的值

要想成功发送请求头部信息,getResponseHeader()方法必须在open()与send()之间调用。

getAllResponseHeaders()

这个方法可以取得一个包含所有头部信息的长字符串。

GET请求

GET是最常见的请求类型,常用于向服务器查询某些信息。使用GET请求时常用到encodeURIComponent()方法。查询字符串中每个参数的名称和值都必须使用encodeURIComponent()进行编码,才能放到URL末尾。完整的函数如下:

1
2
3
4
5
function addURLParam(url,name,value){
url+=(url.indexOf("?") == -1 ? "?" : "&");
url+=encodeURIComponent(name)+"="+encodeURIComponent(value);
return url;
}

POST请求

POST请求通常用于向服务器发送应该被保存的数据。
虽然大部分情况下都能用更简单、更快的GET请求,但在以下情况中,请使用POST请求:

  • 无法使用缓存文件(更新服务器上的文件或数据库)
  • 向服务器发送大量数据(POST 没有数据量限制)
  • 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

默认情况下,服务器对POST请求和提交表单的请求并不会一视同仁,不过我们可以使用XHR来模仿表单提交。

1
2
3
4
xhr.open("POST","example.php",true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //设置表单提交时的内容类型
var form = document.getElementById("#test"); //得到表单中的数据
xhr.send(serialize(form)); //表单中的数据序列化后发送给服务器

实例

下面看一个完整的栗子:
html代码段

1
2
<input type="button" value="ajax提交" onclick="Ajax();">
<div id="resText"></div>

javascript代码段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Ajax() {
var xhr; //声明一个对象用来装入XMLHttpRequest
if(window.ActiveXObject){ //IE5 IE6实例化XHR对象
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}else if (window.XMLHttpRequest){ //现代浏览器实例化XHR对象
xhr = new XMLHttpRequest();
}
xhr.open("get","test.php",true); //启动请求
xhr.onreadystatechange=fun; //触发回调函数
xhr.send(null); //发送请求
function fun() { //定义回调函数
if(xhr.readyState == 4){
if(xhr.status == 200){
document.getElementById("resText").innerHTML=xhr.responseText;
}
}
}
}