Ajax入门 基础概念与方法

 

 

XMLHttpRequest对象

 

除IE以外所有的浏览器都支持直接使用XMLHttpRequest对象。而IE是通过创建ActiveXObject来创建类似的对象。这里给出一种包装方法使得IE5以上的IE版本也能具有XMLHttpRequest对象,这样我们在使用XMLHttpRequest对象的时候可以使用同一的创建方法:

 

(来自《精通JavaScript》)

if  ( typeof  XMLHttpRequest  ==   ' undefined ' ) {
    XMLHttpRequest 
=   function () {
        
return   new  ActiveXObject(
            navigator.userAgent.indexOf(
" MSIE 5 " >=   0   ?   " Microsoft.XMLHTTP "  :  " Msxml2.XMLHTTP "
        );
    }
}

 

发送请求

 

GET请求

 

只支持发送串行化数据(下文会有具体例子)

 

以下是GET请求发送的简单例子

 

     //  创建对象
     var  xml  =   new  XMLHttpRequest();
    
//  初始化
    xml.open( " GET " " test.html " true );
    
//  发送
    xml.send();

 

POST请求

 

POST请求发送方式与GET请求发送方式类似,下文具体。

 

请求状态

 

我们可以通过XMLHttpRequest对象中的readyState监视请求的状态。readyState是一个整型值,各自代表的状态是:

 

0 = 未初始化

1 = 已初始化 (有些书将此状态注为下载,实际测试发现初始化后、未发送请求之前,状态已经修改为1)

2 = 下载已完成

3 = 交互的(响应被部分接收)

4 = 完成

 

在我们的Ajax应用中,一般只需要使用4-完成状态。

 

当请求状态变化时,会触发onreadystatechange事件,我们处理ajax响应就是为这个事件绑定处理函数。

 

客户端完整示例

 

以下结合上述内容,写一个完整的客户端ajax示例

 

     var  xml  =   new  XMLHttpRequest();
    
    
//  未初始化 xml.readyState 为 0
    xml.open( " POST " " test.html " true );
    
//  已初始化 xml.readyState 为 1
    
    xml.setRequestHeader(
" Content-Type " " application/x-www-form-urlencoded " );
    
if  (xml.overrideMimeType)
        xml.setRequestHeader(
" Connection " " close " );
    
    
//  绑定状态变化事件处理函数
    xml.onreadystatechange  =   function () {
        alert(xml.readyState);
    }
    
    xml.send(
" abc " );

 

数据对象的格式

 

根据数据对象的特点,我们可以选择合适的发送方式。

 

串行化

 

利用HTTP GET标准请求,即类似: http://www.zhengchuyu.cn/?name=zcy&nick=donald 的传输方式。

 

我们需要有一个串行化函数,并且是针对表单元素和键值对对象设计的。(不能串行化多选按钮)

 

function  serialize(a) {
    
var  s  =  [];
    
if  (a.constructor  ==  Array) {
        
//  表单元素数组
         for  ( var  i  =   0 ; i  <  a.length; i ++ ) {
            s.push( a[i].name 
+   " = "   +  encodeURIComponent(a[i].value));
        }
    }
    
else  {
        
//  键值对对象
         for  ( var  j  in  a)
            s.push(j 
+   " = "   +  encodeURIComponent(a[j]));
    }
    
return  s.join( " & " );
}

 

GET请求发送串行化数据

 

     var  xml  =   new  XMLHttpRequest();
    xml.open(
" GET " " test.html? "   +  serialize(data),  true );
    xml.send();

 

POST请求发送串行化数据

 

     var  xml  =   new  XMLHttpRequest();
    xml.open(
" POST " " test.html " true );
    
//  设置content-type头部信息,告诉服务器如何解析我们发送的数据
    xml.setRequestHeader( " Content-Type " " application/x-www-form-urlencoded " );
    
//  保证浏览器发送的串行化数据长度正确
     if  (xml.overrideMimeType)
        xml.setRequestHeader(
" Connection " " close " );
    
//  串行化数据发送
    xml.send(serialize(data));

 

xml

 

后文详述。 

 

json

 

后文详述

 

HTTP响应

 

上文已经提到可以通过判断readyState的值得知请求状态,我们可以知道客户端是否已经获得了服务器响应。但是服务器并不是每一次都能正常响应,这时我们需要通过服务器响应代码(保存在返回结果对象的status变量中)判断响应情况。

 

状态码

 

成功响应 200~300

未修改响应 304

本地文件 无状态码

 

另外有一个特殊情况(来自《精通JavaScript》,没有验证),Safari浏览器中,如果文档自上次请求未曾修改过,会返回状态码“undefined”,比较怪异。

 

以下给出一判断XMLHttpRequest对象是否处于成功响应状态的兼容函数

 

function  httpSuccess(r) {
    
try  {
        
return   ! r.status  &&  location.protocol  ==   " file: "  
            
||  (r.status  >=   200   &&  r.status  <   300
            
||  r.status  ==   304
            
||  navigator.userAgent.indexOf( " Safari " >=   0   &&   typeof  r.status  ==   " undefined " ;
    }
    
catch (e) {
        
return   false ;
    }
}

 

超时检查

 

超时检查比较简单,就是用一个变量记录是否超时,在send发送之前用一个setTimeout设定在某个时间段后把该变量标记为超时,并在状态改变响应函数中检测这一变量就行了。 

 

服务器返回数据

 

服务器可以返回任何格式的数据。一般比较常用的是XML、HTML、JavaScript/JSON。

 

获取数据

 

获取数据通过XMLHttpRequest的两个重要属性:responseXML和responseText。

 

responseXML 可以获取XML,即服务器明确指出“Content-Type:text/xml”时才可以由这个属性获取。

responseText 可以获取HTML和JavaScript类型的数据。

 

指定类型解析数据

 

以下是一个按指定类型解析数据的函数

 

(来自《精通JavaScript》,为了便于理解,稍有改动) 

 

//  type可选值:xml, script, text, html 默认值:空
function  httpData(r, type) {
    
var  ct  =  r.getResponseHeader( " content-type " );
    
var  data  =   ! type  &&  ct  &&  ct.indexOf( " xml " >=   0 ;
    data 
=  (type  ==   " xml "   ||  data)  ?  r.responseXML : r.responseText;
    
if  (type  ==   " script " )
        eval.call(window, data);
    
return  data;
}

 

你可能感兴趣的:(Ajax)