站长中国
设为首页 | 帮助中心

站长论坛 站长下载
您所在的位置: 站长中国 > 站长专栏 > DEDECMS专栏 > 技术文档 > 正文

DEDECMS Ajax技术入门教程
  2007年08月06日13:30:44  评论(1条) 字体:[ ]
相关热点:教程 入门 if 发送 var // function 请求 new
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:


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:

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:

<script language='javascript' src='dedeajax.js'></script>
<script language='javascript'>
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");

</script>

<div id='myinfo'><div>

test.php
CODE:

<?
header("Content-Type: text/html; charset=gb2312");
echo $_POST['key1'];
?>

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

把类里面的
CODE:

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:

//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']);

正常了吧:lol:

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

三、xmldom 的使用方法

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

test2.php
CODE:

<?
header("Content-Type: text/xml; charset=gb2312");
echo '<'.'?'."xml version=\"1.0\" encoding=\"gb2312\" ".'?'.">
<myhome>
<item sex=\"男\">我是小一</item>
<item sex=\"女\">我是小二</item>
</myhome>
";
?>


这个xml文档在客户端用自己的方式展现出来。

因为xml这种东西比较麻烦,所以语法也必须严格,test2.htm的页面的源码为
CODE:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>ajax测试</title>
</head>
<body onload="WiteLoadDocument()">
<script language='javascript' src='dedeajax.js'></script>
<script language='javascript'>
var myajax = new DedeAjax(WiteOK);
function WiteOK()
{
   var myinfo = document.getElementById("myinfo");
   var mydom = null;
   myinfo.innerHTML = "以下是处理结果:<br/>";
   if(myajax.xhttp.readyState == 4){
   mydom = myajax.xhttp.responseXml;
   alert(mydom);
   }
}
function WiteLoadDocument()
{
   myajax.SendGet("test2.php");    
}
</script>
<div id='myinfo'><div>
</body>
</html>

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

那下面是处理:

CODE:

function WiteOK()
{
   var myinfo = document.getElementById("myinfo");
   var mydom = null;
   myinfo.innerHTML = "以下是处理结果:<br/>";
   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 +"<br/>";
   }
   }
}

结果:
CODE:

以下是处理结果:
我是:我是小一,我的性别是:男
我是:我是小二,我的性别是:女

责任编辑:

收藏本文 打印 打印本文  推荐本文 告诉好友 投稿 投稿邮箱

站长排行

专栏

学院

新闻

盈利

ECSHOP模板制作参考文档
悬挂阿里妈妈会否被百度惩罚
阿里妈妈是否是中小站长的救世主?
最强网店ECShop发新版 众多酷炫功能给
ECSHOP模板下载
土豆网,优酷网,爆米花等视频网站采集
网上商店系统巅峰对决 ECShop vs ShopE
DedeCms模板安装/制作概述
艰难的走在创业的路上 第一天
编程中国全站采集规则
[揭密网络黄链]中国留学生买凶专破日本
超强弹出窗口代码,什么都挡不住
JSP语法(6)
贴吧发帖机使用教程(绝对原创)
FLASH视觉特效实例之地震效果
关于数据分页(转自www.codeproject.co
ASP实现文件直接下载
Photoshop制作光感超酷效果水晶球
 遍历ASP.NET页面控件
永远的后门[经典]+查不出的后门
淘宝网卖家公然叫卖“艳照门”照片集
驳《百度Hi面世对腾讯有利》
国内各IT企业办公环境揭秘(多图)
Google绿色专家质疑黑色背景网页节省资
阿里妈妈广告卖主全攻略
站长创业源动力 主流站长站赏析
推荐阅读:80年小子的创业道理
Discuz!6.0猛将出击 最强论坛程序酷炫
我的网络,我的团队:专访李文明
百度新闻频道改版十天 流量止跌反弹翻
性福联盟 一个不尊重站长的联盟
大脚:日赚100元—揭露最新firefox欺骗
大脚:垃圾站超级赚钱法之二—突破“站
大脚:垃圾站超级赚钱法之——前言
迅雷联盟、快车联盟收入对比
经理人必看的十个管理网站
Google Adsense的秘密 第二版
西联汇款兑付城市查询
不用SEO取得成功的10个步骤
关于做GOOGLE的五条经验
站长学院  网页设计 建站教程 图形图象 网络编程

windows 2008中
windows 2008中
Photoshop CS3
Photoshop CS3

中国是间谍软件最大受害国 来
南征北战 双线路网站解决办法
王建然之欲望和理想的对话
windows 2008中文版iis7+asp+p
北大青鸟搜索引擎广告策略案例
网站推广高人的8点心得
几个颇有创意的网站推广方法

新闻线索

如果你有站长界人事变动、重组并购、变革技术出现,以及产品投诉等重要新闻线索,请告诉我们,我们会给予特别关注。
0631-3653338
站长中国编辑部
站长中国24小时新闻热线: 13256307008