Ajax详解

一:什么是Ajax?

    Ajax:是对Asychronoous Javascript + XML的简写,是一种和服务器交换数据的技术,这一技术无须刷新页面就可以从服务器取得数据。

    但注意,虽然名字中包含XML,但Ajax通信与数据格式无关。

二:XMLHttpRequest对象(简称XHR    本文中简称小X)

    该对象是实现Ajax技术的核心,小X能够以异步方式帮我们从服务器取得数据,也就意味着用户单击后,可以不必刷新页面也能取得新数据,也就是说,可以使用XHR对象取得新数据,然后再通过DOM将新数据插入到页面中。

   2.1  创建XHR对象

        IE7+、Firefox、Opera、Chrome和Safari都支持原生的XHR对象。在这些浏览器中直接调用XMLHttpRequest构造函数来创建即可,如下

var xhr = new XMLHttpRequest();
2.1.1 兼容性问题
    如果你想考虑到ie7以下的版本,那么便不能用上面的办法创建XHR对象。

    在IE5中,我们的小X是通过MSXML库中一个叫做ActiveX的对象实现的。这便导致了在IE中,我们可能会遇到三个不同版本的XHR对象,分别是MSXML2.XMLHttp、MSXML2.XMLHttp.3.0、MSXML2.XMLHttp.6.0。      那么这时我们如果还想用XHR对象的话,就需要编写一个函数来确定到底要用哪个版本的XHR了。  

//适用于IE7以前的版本
function createXHR() {
    if(typeof arguments.callee.activeXString != "string") {
	var versions = ["MSXML2.XMLHttp", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp6.0"], i, len;
	for(i=0, len=versions.length; i<len; i++) {
	    try{
	        new ActiveXObject(versions[i]);
	        arguments.callee.activeXString = versions[i];
	        break;
	    } catch(ex) {
	        //直接跳过不处理,继续循环
	       }
	    }
	}
    return new ActiveXObject(arguments.callee.activeXString);
}

函数分析:

    我们来分析一下这个函数,写的确实很妙,(人家现有的啊,不是我写的啊),arguments.callee指向当前函数体内正在执行的函数,这里就是createXHR函数本身。函数刚进去的时候,当然没有activeXString属性了,所以肯定不等于string,直接进去if,然后将这三个不同的版本名称都放在一个数组中,对每一个版本进行循环,如果当前版本可以用来创建一个ActiveXObject对象,那么我们给当前函数加一个activeXString属性,并赋值为该版本名称,直接跳出循环。如果不能创建ActiveXObject对象,那么就会抛出异常,被catch抓住,不处理,继续循环,直到找到一个能够创建该对象的版本。如果循环完了,三个版本都不能创建ActiveXObject对象,那么就会抛出thrownewError("NoXHRobjectavailable.")的异常,啧,贼惨了这就。


        那么这样的话,我们就可以创建一个函数来兼顾所有的浏览器了,我就不信哪位哥还用IE5-。

function createXHR() {
    if(typeof XMLHttpRequest != "undefined") {
	return new XMLHttpRequest();
    } else if(typeof ActiveXObject != "undefined") {
	if(typeof arguments.callee.activeXString != "string") {
	    var versions = ["MSXML2.XMLHttp", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp6.0"], i, len;
	    for(i=0, len=versions.length; i<len; i++) {
	        try{
	            new ActiveXObject(versions[i]);
	            arguments.callee.activeXString = versions[i];
	            break;
	        } catch(ex) {
		    //直接跳过不处理,继续循环
	          }
	    }
	}
	return new ActiveXObject(arguments.callee.activeXString);
    } else {
	throw new Error("No XHR object available.");
    }
}

该函数先检测原生XHR对象是否存在,如果存在则直接返回它的新实例。如果原生XHR对象不存在,则检测ActiveX对象,如果都不存在,就抛出一个错误。啧,贼惨了这就。

呼,处理个兼容真烦,万恶的IE!!那么终于我们可以直接一句话创建可爱的小X了

var xhr = createXHR();

2.2 XHR的用法

2.2.1  open()

    要调用的第一个方法是open(),它接受三个参数:要发送的请求类型("get", "post"等)、请求的url和表示是否一部发送请求的布尔值。   举个梨子:

xhr.open("get", "haha.php", false);   //会启动一个针对haha.php的GET请求,因为是此url为相对路径,相对于当前页面(当然也可以使用绝对路径)
2.2.2 send()

调用open()以后并不会真正发送请求,而只是启动一个请求以备发送。要发送特定请求,必须调用send()方法

xhr.open("get", "haha.php", false);  
xhr.send(null);

这里的send()方法接受一个参数,既要作为请求主体发送的数据。如果不需要通过请求主体发送数据,则必须传入null,因为这个参数对有些浏览器来说是必须的。


2.2.3  判断响应状态,接收数据
2.2.3.1   同步请求

由于我们这次的请求是同步的,js代码会等到服务器相应之后在继续执行。在收到响应后,响应的数据会自动填充小X的属性。

responseText: 作为相应主体被返回的文本(即服务器返回的数据)

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

status: 响应的Http状态码

statusText: Http状态的说明

在收到响应后,第一步是检查status的属性,以确定响应是否成功,一般来说以2开头的状态码和304都可表示响应成功。所以检测响应状态的代码如下:

xhr.open("get", "haha.php", false);  
xhr.send(null);

if((xhr.status >= 200 && xhr.status <= 300) || xhr.status == 304) {
    alert(xhr.responseText);          //服务器响应成功
} else {
  alert("Request was unseuccessful: " + xhr.status)       //服务器响应失败
}
2.2.3.2  异步请求

    多数情况下,我们还是要发送异步请求,才能让javascript代码继续执行而不必等待响应。

    此时我们可以检测XHR的readyState属性,该属性表示请求/响应过程的当前活动阶段。该属性取值如下:

    0:为初始化。尚未调用open()方法。

    1:启动。已调用open()方法,但尚未调用send()方法。

    2:发送。以调用send()方法,但尚未接受到响应。

    3:接受。已经接受到部分相应数据。

    4:完成。已经接受到全部相应数据,而且已经可以在客户端使用了。


    readystatechange事件

        只要readyState的值由一个值变为另一个值,就会触发该事件。利用该事件,我们可以检测当前该请求所处的活动阶段。来看一个梨子:

    

var xhr = createXHR();
//该事件一定要写在open()方法前面,这样才能确保跨浏览器兼容性
xhr.onreadystatechange = function() {             
if(xhr.readyState == 4) {  //我们只关心活动阶段为4的值,因为这时所有数据才准备就绪,我们才能用这些数据
    if((xhr.status >= 200 && xhr.status <= 300) || xhr.status == 304) {
        alert(xhr.responseText);          //服务器响应成功
    } else {
        alert("Request was unseuccessful: " + xhr.status)       //服务器响应失败
      }
    }
}
xhr.open("get", "haha.php", true);
xhr.send(null);

2.2.4 abort()

    在接受到响应之前可以调用该方法来取消异步请求。

  xhr.abort();


三:怎样发送数据

    3.1  GET请求

            get是最常见的请求类型,最常用于向服务器查询某些信息。

     当xhr对象的请求方式为get时,一般将数据作为查询字符串追加到url的末尾,发送给服务器。但有的人可能总会碰到查询字符串格式有误的问题,这就是我们要注意的,在使用get请求时,查询字符串中每个参数的键和值都要进行encodeURIComponent()编码。才能放到URL末尾。而且所有名-值对之间都必须用&连接。举个梨子:

xhr.open("get", "haha.php?name1=value1&name2=value2", true);

我们来看一个函数:

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

该函数的用途是格式化我们的url,以符合刚才说的查询字符串的要求(上面的红字),建议大家使用该方法,可使查询字符串格式良好,并可靠的用于XHR对象

代码很简单,这里我就不再赘述。上一个使用这个函数构建ajax请求的梨子:

var url = "haha.php"
			
//添加参数
url = addURLParam(url, "name", "Bell");
url = addURLParam(url, "age", "20");
			
var xhr = createXHR();
xhr.open("get", url, true);


3.2 post请求

    post请求通常用于向服务器发送应该被保存的数据。应该把数据作为请求的主体提交。(即放到send中)

    post请求发送的数据可以包含非常多的数据,且格式不限。举个梨子

  

  var person = {
         name: "张三",
         age: 15
  }

xhr.send(JSON.stringify(person));          //这里我发一个json过去给服务器

3.3 get和post对比

    

 getpost
用途常用于向服务器查询某些信息常用于向服务器发送应该被保存的数据
数据格式查询字符串格式不限
数据位置URL末尾send()函数内部
资源消耗 比get请求消耗的资源会更多一些
性能角度get请求的速度最多可达到post请求的两倍 
数据字节大小(注意这里的限制是对整个url来说的)最多只能是1024字节IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。
安全性可以从浏览器的历史记录中读取到这些数据,会产生严重的安全问题。相对来说就可以避免这些问题,个人觉得也没有安全到哪儿去。



    

    
    
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值