精通ajax,一日精通Ajax技术

一日精通Ajax技术

Ajax这个名称怎么来的,本人也不得而之了,大概是(Active

Javascript Action Xml)吧,说白一点就是运用了 javascript、xmlhttp和xmldom技术及网站后台来处理用户的一些操作的方法吧。

那么本人就分三步来说明如何使用 Ajax 技术来做开发。

一、用 javascript 操作 xmlhttp 对象

二、服务器部对xmlhttp请求的响应(PHP范例)

三、xmldom 的使用方法

先说第一部份:

一、用 javascript 操作 xmlhttp 对象

IE7, Mozilla ,Firefox等浏览器中,javascript是内置有 XMLHttpRequest 这个对象的,但IE5+则没有,需要用如下方法来启动:

//IE 6

try{ xhttp = new ActiveXObject("Msxml2.XMLHTTP";} catch(e){ ; }

//IE5+

if(xhttp == null) try { xhttp = new

ActiveXObject("Microsoft.XMLHTTP";} catch(e){ ; }

那考虑不同浏览器的兼容,启动一个xmlhttp一般都要按如下方式:

CODE:[Copy to clipboard]var xhttp = null;

if(window.XMLHttpRequest){ //IE7, Mozilla ,Firefox 等浏览器内置该对象

xhttp = new XMLHttpRequest();

}else if(window.ActiveXObject){ //IE6、IE5

try{ xhttp = new ActiveXObject("Msxml2.XMLHTTP");}

catch (e){ ; }

if( xhttp == null) try { xhttp = new

ActiveXObject("Microsoft.XMLHTTP");} catch (e){; }

}

对于 xmlhttp 的使用,一般遵守如下的顺序:

1、初始化 xmlhttp 对象(上文);

2、打开链接

方法

xhttp.open("GET", purl, true);

参数一:用 GET 或 POST 方式发送数据

参数二、请求网址(只能请求你服务器上的资源,一般浏览器安全限制不能读取跨域的数据)

参数三、true 表示异步传输(服务器返回信息完成前,你可以进行其它操作),false 表示阻断方式的传输。

3、设定要发送的 http 请求头

方法:

xhttp.setRequestHeader(key,value);

一般来说,默认要发送的头是:xhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded";

这种表示发送的内容类型的请求头用于发送文本数据,而且javascript默认是以unicode发送的,还有另外一种形式是:xhttp.setRequestHeader("Content-Type","multipart/form-data";这表示发送二制形式的数据,由于安全性原因,javascript一般不能用这种方式来发送数据,所以这个头一般没什么用。

如果你的网站开启了使用 refer 参数来防盗链,那么你必须用这个方法指定 Refer 参数,或者如果用户需要登录才能进行某操作,那么要指定 Cookie 的请求头。

4、send 数据

方法:xhttp.send(postdata);

对于用 get攻手请求,不需要指定postdata,直接用 test.php?a=a&b=b 这样形式的网址来请求即可。

如果是post方式,需要用

key1=value2&key2=value2 这样的形式来对数据进行处理,把它合并在

postdata 字串中,然后发送。

注意事项:

javascript默认发送数据的方式是unicode,处理返回的数据必须是utf-8格式,因此,在发送的时候,需要用escape()函数来处理postdata和网址的value,在服务器上必须还原这些value,并把unicode转为页面编码值,因此如果用 jsp 或 asp.net 都会比较简单,但如果用php处理起来是什么费劲的,等下会教你如何做。

5、确认服务器返回资料完成下载

[1] 如果用阻断的方式来发送请求,那么直接用

if(xhttp.readyState == 4)就能判断是否完成。

readyState 的具体属性值为:

0 没open

1 没send

2 状态未知

3 正在传送

4 传送完成

当然为了保障起见,还需要加多一重判断,就是 if(xhttp.status == 200) ,status 就是 http 协议里的返回头代码

1xx 表示(唉呀,忘记了)

2xx 表示成功的信息

3xx 表示页面转移

4xx 页面不存在

5xx 表示服务器的各种错误

如果你的页面没特殊处理,一般用 if(xhttp.status == 200)  来确信内容返回是正确的

[2] 如果用异步传输,需要用

onreadystatechange 的事件来监听

xhttp.onreadystatechange = function()

{

//这里来进行上面阻断方式的判断

if(myajax.xhttp.readyState == 4){

if(myajax.xhttp.status == 200){

//要进行的后续操作

}

}

}

6、获取返回结果

属性:

[1]xhttp.responseBody;

[2]xhttp.responseStream;

[3]xhttp.responseXml;

[4]xhttp.responseText;

其中1、2都是二进制的方式,一般很少会用到,4不用看都知道了

如果服务端无意外的话[3]返回的是一个xmldom的对象

二、服务器部对xmlhttp请求的响应(PHP范例)

为了简化操作,在这里把 xmlhttp的各作操作封装为一个类

CODE:[Copy to clipboard]function DedeAjax(WiteOKFunc){

//WiteOKFunc 为异步状态事件处理函数

//xmlhttp和xmldom对象

this.xhttp = null;

this.xdom = null;

//post或get发送数据的键值对

this.keys = Array();

this.values = Array();

this.keyCount = -1;

//http请求头

this.rkeys = Array();

this.rvalues = Array();

this.rkeyCount = -1;

//请求头类型

this.rtype = 'text';

//初始化xmlhttp

if(window.XMLHttpRequest){//IE7, Mozilla ,Firefox 等浏览器内置该对象

this.xhttp = new XMLHttpRequest();

}else if(window.ActiveXObject){//IE6、IE5

try { this.xhttp = new

ActiveXObject("Msxml2.XMLHTTP");} catch (e) { }

if (this.xhttp == null) try { this.xhttp = new

ActiveXObject("Microsoft.XMLHTTP");} catch (e) { }

}

this.xhttp.onreadystatechange = WiteOKFunc;

//rs: responseBody、responseStream、responseXml、responseText

//以下为成员函数

//--------------------------------

//初始化xmldom

this.InitXDom = function(){

var obj = null;

if (typeof(DOMParser) != "undefined") { // Gecko、Mozilla、Firefox

var parser = new DOMParser();

obj = parser.parseFromString(xmlText, "text/xml");

} else { // IE

try { obj = new

ActiveXObject("MSXML2.DOMDocument");} catch (e) { }

if (obj == null) try { obj = new

ActiveXObject("Microsoft.XMLDOM"); } catch (e) { }

}

this.xdom = obj;

};

//增加一个POST或GET键值对

this.AddKey = function(skey,svalue){

this.keyCount++;

this.keys[this.keyCount] = skey;

this.values[this.keyCount] =

escape(svalue);

};

//增加一个Http请求头键值对

this.AddHead = function(skey,svalue){

this.rkeyCount++;

this.rkeys[this.rkeyCount] = skey;

this.rvalues[this.rkeyCount] =

svalue;

};

//清除当前对象的哈希表参数

this.ClearSet = function(){

this.keyCount = -1;

this.keys = Array();

this.values = Array();

this.rkeyCount = -1;

this.rkeys = Array();

this.rvalues = Array();

};

//发送http请求头

this.SendHead = function(){

if(this.rkeyCount!=-1){ //发送用户自行设定的请求头

for(;i<=this.rkeyCount;i++){

this.xhttp.setRequestHeader(this.rkeys[i],this.rvalues[i]);

}

}

if(this.rtype=='binary'){

this.xhttp.setRequestHeader("Content-Type","multipart/form-data");

}else{

this.xhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

}

};

//用Post方式发送数据

this.SendPost = function(purl){

var pdata = "";

var i=0;

this.state = 0;

this.xhttp.open("POST",

purl, true);

this.SendHead();

if(this.keyCount!=-1){ //post数据

for(;i<=this.keyCount;i++){

if(pdata=="") pdata = this.keys[i]+'='+this.values[i];

else pdata += "&"+this.keys[i]+'='+this.values[i];

}

}

this.xhttp.send(pdata);

};

//用GET方式发送数据

this.SendGet = function(purl){

var gkey = "";

var i=0;

this.state = 0;

if(this.keyCount!=-1){ //get参数

for(;i<=this.keyCount;i++){

if(gkey=="") gkey = this.keys[i]+'='+this.values[i];

else gkey += "&"+this.keys[i]+'='+this.values[i];

}

if(purl.indexOf('?')==-1) purl = purl + '?' + gkey;

else  purl = purl +

'&' + gkey;

}

this.xhttp.open("GET",

purl, true);

this.SendHead();

this.xhttp.send();

};

} // End Class DedeAjax

上面代码保存为: dedeajax.js

ok 那现在做个最简单的测试吧

test.htm

CODE:[Copy to clipboard]

function WiteOK()

{

var myinfo = document.getElementById("myinfo");

if(myajax.xhttp.readyState == 4){

if(myajax.xhttp.status == 200){

myinfo.innerHTML = myajax.xhttp.responseText;

}

}

}

var myajax = new DedeAjax(WiteOK);

myajax.AddKey("key1","----------------------------");

myajax.SendPost("test.php");

test.php

CODE:[Copy to clipboard]

header("Content-Type: text/html; charset=gb2312");

echo $_POST['key1'];

?>

看到了什么了呢?不用激动,真正让你头痛的东西还没有出来。

把类里面的

CODE:[Copy to clipboard]this.AddKey =

function(skey,svalue){

this.keyCount++;

this.keys[this.keyCount] = skey;

this.values[this.keyCount] = svalue;//escape(svalue);

};

escape 屏蔽掉

发送

myajax.AddKey("key1","-----中---国----人-----";

看到什么了,乱码是吧?呵呵,这回开始头大了

先把 escape放回去

this.values[this.keyCount] = escape(svalue);

那么看到的就是

-----%u4E2D---%u56FD----%u4EBA-----

如何把  %u4E2D  这些东西弄回来呢?对于php而言这是一个很复杂的问题,如果用asp就简单多了

下面是我写的一个函数:

CODE:[Copy to clipboard]//unicode url编码转gbk编码函数

function Unicode2Gbk($str)

{

//载入对照词典

if(!isset($GLOBALS['GbkUniDic']))

{

$ds =

file("./data/gbk_unicode.dic");

foreach($ds as $l){

$GLOBALS['GbkUniDic'][hexdec('0x'.substr($l,0,4))] = substr($l,5,4);

}

}

//处理字符串

$glen = strlen($str);

$okstr = "";

for($i=0; $i < $glen; $i++)

{

if( $glen-$i >

4){

if($str[$i]=='%' && $str[$i+1]=='u'){

$uni = hexdec('0x'.substr($str,$i+2,4));

if(isset($GLOBALS['GbkUniDic'][$uni])){

$uni = $GLOBALS['GbkUniDic'][$uni];

$okstr .= chr(hexdec(substr($uni,0,2))).chr(hexdec(substr($uni,2,2)));

}

else $okstr .= "{".hexdec("0x".$uni).";";

$i = $i+5;

}

else $okstr .= $str[$i];

}

else $okstr .=

$str[$i];

}

return $okstr;

}

词典文件: http://www.ce86.com/myimg/data.rar

把test.php 输出改为

echo Unicode2Gbk($_POST['key1']);

正常了吧

以下说下面和xml有关的东西的了

三、xmldom 的使用方法

由于本文仅是牵针引线的作用,这一章就简单些,因为针对的是 php ,如果针对的是 asp.net 或 jsp 写涉及 web server 类的通信,已经不单纯是 ajax  的问题了,本章的任务是把test2.php

CODE:[Copy to clipboard]

header("Content-Type: text/xml; charset=gb2312");

echo '

encoding=\"gb2312\" ".'?'.">

我是小一

我是小二

";

?>这个xml文档在客户端用自己的方式展现出来。因为xml这种东西比较麻烦,所以语法也必须严格,test2.htm的页面的源码为

CODE:[Copy to clipboard]

ajax测试

var myajax = new DedeAjax(WiteOK);

function WiteOK()

{

var myinfo = document.getElementById("myinfo");

var mydom = null;

myinfo.innerHTML = "以下是处理结果:
";

if(myajax.xhttp.readyState == 4){

mydom = myajax.xhttp.responseXml;

alert(mydom);

}

}

function WiteLoadDocument()

{

myajax.SendGet("test2.php");

}

在IE中测试一下,如果弹出的对话框是 [object] 就表示成功获得返回的xml的xmldoc了。

那下面是处理:

CODE:[Copy to clipboard]function WiteOK()

{

var myinfo = document.getElementById("myinfo");

var mydom = null;

myinfo.innerHTML = "以下是处理结果:
";

if(myajax.xhttp.readyState == 4){

mydom = myajax.xhttp.responseXml;

var nodeList =

mydom.selectNodes("/myhome/item");

var mynode = null;

var myatt = null;

var mysex = "";

for(i=1;i<=nodeList.length;i++)

{

mynode = nodeList[i-1];

for(j=0;j < myinfo.attributes.length;j++)

{

if(!mynode.attributes[j]) break;

myatt = mynode.attributes[j];

if(myatt.name=='sex') mysex = myatt.value;

}

myinfo.innerHTML += "我是:"+mynode.text+",我的性别是:"+ mysex +"
";

}

}

}

结果:

CODE:[Copy to clipboard]以下是处理结果:

我是:我是小一,我的性别是:男

我是:我是小二,我的性别是:女

OK,目的已经达到

关于dom的部份只在IE6中测试过,可能在firefox中会有问题,大家可能参考与兼容性有关的文档。

posted on 2007-06-13 10:26 chenguo 阅读(83) 评论(0)  编辑  收藏 所属分类: AJAX Dev

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值