一日精通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]<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:[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 '<'.'?'."xml version=\"1.0\" encoding=\"gb2312\" ".'?'.">
<myhome>
  <item sex=\"男\">我是小一</item>
  <item sex=\"女\">我是小二</item>
</myhome>
";
?>这个xml文档在客户端用自己的方式展现出来。因为xml这种东西比较麻烦,所以语法也必须严格,test2.htm的页面的源码为

CODE:[Copy to clipboard]<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>ajax测试</title>
</head>
<body >
<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:[Copy to clipboard]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:[Copy to clipboard]以下是处理结果:
我是:我是小一,我的性别是:男
我是:我是小二,我的性别是:女
OK,目的已经达到

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

时间: 2024-08-31 12:37:09

一日精通Ajax技术的相关文章

争论:Ajax技术是否即将没落?

ajax 在孟岩老师11月21日的blog(http://blog.csdn.net/myan/archive/2006/11/21/1402346.aspx)中说他惊艳于微软公司新近推出的界面开发工具Expression,并且预言基于Web标准(通常即XHTML+CSS+javascript)的界面开发技术很快就会没落.孟岩预测:"最迟不超过2008年,在WPF.Flash(Apollo)等RIA技术的夹攻之下,越来越多的Web应用将同时部署传统Web页面和新的RIA UI." 对于

asp.net中ajax技术是否可以实现停止服务器端正在运行的按钮事件

问题描述 asp.net中ajax技术是否可以实现停止服务器端正在运行的按钮事件 给予B/S的webform项目 在服务器端有一个按钮事件 执行时间较长 所以就添加了一个按钮用来可以随时停止正在运行的耗时较长的按钮 问题是那个正在服务器端运行的按钮是否可以被其他按钮终止呢?求解答 解决方案 不可以.首先将长时间操作的任务放在按钮事件中就是错误的.按钮事件在页面回传前调用,ajax回发根本在页面加载后.你应该用消息队列.后台服务去执行长时间的任务. 解决方案二: 这个理论上是可以实现的. 服务器端

探讨:利用AJAX技术提高搜索引擎排名

描述 嵌入在你的web页面中的导航元素能够降低你的搜索引擎评价排名并且降低你的网站的响应性能.本文作者想同你一起探讨如何使用AJAX技术来解决这两个问题. 许多设计良好的web站点都包含大量的与实际内容相联系的可导航信息.用于导航的HTML标记能影响你的搜索引擎评价,而且能够改进访问者的页面下载体验感.在本文中,你会看到如何使用AJAX来创建更为集中的更快速加载的web页面. 一. 分离导航与内容 让我们使用一个例子作为开始.请考虑你现在阅读的文章,它有下列一些内容: · 一个其上有一些预定义的

创建基于AJAX技术的Scribble应用程序

简介 ASP.NET Atlas是一套丰富的类库,用于ASP.NET开发AJAX风格的应用程序.本文试图解说Atlas框架的一般性特征,由于Atlas是一个庞大的库,故本文集中探讨Atlas的两个最重要的特征: 1. 能够从客户端脚本中调用服务器端web服务 2. 使得开发跨浏览器兼容的JavaScript代码相当容易 通过对这两个特征的介绍,读者朋友可以熟悉Atlas类库的使用方法. 背景 MFC Scribble应用程序是学习MFC编程的著名例子之一.Scribble应用程序允许用户使用鼠标

前端Ajax技术原理

ajax所包含的技术 大家都知道ajax并非一种新的技术,而是几种原有技术的结合体.它由下列技术组合而成. 1.使用CSS和XHTML来表示. 2. 使用DOM模型来交互和动态显示. 3.使用XMLHttpRequest来和服务器进行异步通信. 4.使用javascript来绑定和调用. 在上面几中技术中,除了XmlHttpRequest对象以外,其它所有的技术都是基于web标准并且已经得到了广泛使用的,XMLHttpRequest虽然目前还没有被W3C所采纳,但是它已经是一个事实的标准,因为目

用ajax技术制作在线歌词搜索功能

最新制作完成的在线歌词搜索功能,利用ajax技术,无刷新显示歌词,只需要输入你要查找的歌曲名或歌词.界面还不是很好看,完善中......  1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2<html xmlns="http://www.w3.

AJAX技术基础介绍

ajax 基于XML的异步JavaScript,简称AJAX,是当前Web创新(称为Web2.0)中的一个王冠.感谢组成AJAX的各种技术,Web应用的交互如Flickr, Backpack和Google在这方面已经有质的飞跃.这个术语源自描述从基于网页的Web应用到基于数据的应用的转换.在基于数据的应用中,用户需求的数据如联系人列表,可以从独立于实际网页的服务端取得并且可以被动态地写入网页中,给缓慢的Web应用体验着色使之像桌面应用一样. 虽然大部分开发人员在过去使用过XMLHttp或者使用I

解开Ajax技术生命中的达芬奇密码

ajax 现在,Ajax技术发展势头迅猛,开发者已经建立了一个调用大量客户端javascript.不断增长的.复杂的系统.因此,在JavaScript上尝试OO技术便成为了管理复杂性的一种手段.在此过程中,多数开发者很快便认识到:JavaScript是一种原型化的(prototypical)语言,它缺少OO自身带来的多种便利. 几乎每位在开发JavaScript时尝试应用面向对象技术的开发者,或多或少都会问自己一个问题:"如何调用父类(super class)的方法?"在Ajax技术还

如何使用Ajax技术开发Web应用程序(3)

ajax|web|程序 在这个关于AJAX系列的第三部分中(相关文章:第一部分.第二部分),我们将学习如何使用AJAX与服务端进行写作以及这些技术如何产生强大的web应用程序.如果你对学习如何构建类似GMail或者Google Maps的web程序感兴趣的话,这是一篇基础的入门(虽然那两个东东会比我们在这篇文章中提及的内容复杂的多).在这篇文章中,我使用PHP作为服务端语言,但AJAX能够和任何服务端语言进行很好的兼容,所以你尽可以选择你所钟爱的任何语言! 我们还是从我们上一篇文章的代码(喏,就