stone2083

ajax原理简介以及简单demo演示

如今web应用上,ajax技术是大行其道。
ajax框架层出不穷,prototype,dojo,jquery,mootools,dwr,buffalo,ext,yui,spry。。。
ajax框架的出现,在提升开发生产效率的同时,也让不少同学不明其内在原理,仅仅成为了某些框架的使用者。
(对于产品生产是好事,对于技术追求是坏事)

本文不涉及任何ajax框架的使用,本文仅通过一个模拟需求,在不使用任何ajax框架的前提下,以demo演示的方式,
向大家介绍ajax的原理以及应用场景。

ajax全称是:Asynchronous JavaScript And XML。
其本意是,通过javascript技术(JavaScript),通过异步http请求方式(Asynchronous),得到XML文本内容(XML)之后,通过javascript技术局部刷新web页面内容。
从广义的概念看,只要符合“异步请求,局部刷新web页面”的技术,都可以成为ajax。
未必一定要使用javascript,一般情况下,大多数client端脚本代码都可以;返回内容也未必一定要是xml,目前json格式,更为流行。

如何异步请求内容呢?
以javascript代码作演示,如下:
function xmlhttpPost(url,func) {
    
var xmlHttpReq = false;
    
var self = this;
    
// Mozilla/Safari
    if (window.XMLHttpRequest) {
        self.xmlHttpReq 
= new XMLHttpRequest();
    }
    
// IE
    else if (window.ActiveXObject) {
        self.xmlHttpReq 
= new ActiveXObject("Microsoft.XMLHTTP");
    }
    self.xmlHttpReq.open('POST', url, 
true);
    self.xmlHttpReq.setRequestHeader('Content
-Type', 'application/x-www-form-urlencoded');
    self.xmlHttpReq.onreadystatechange 
= function() {
        
if (self.xmlHttpReq.readyState == 4) {
            func(self.xmlHttpReq.responseText);
        }
    }
    self.xmlHttpReq.send(
null);
  }
参数一,url:表明异步请求的资源地址
参数二,func:表明请求结束后,采用什么函数对请求结果内容进行回调处理

其实,这一个js代码,就诠释了ajax的全部含义--异步请求资源,将得到的资源内容,使用指定的function进行处理。
所以,ajax很简单,大家千万别被如今层出不穷的ajax框架给吓怕了。要了解ajax的原理,就只要参看这段代码即可。
如今的一些框架,仅仅在此基础上,是封装了一些公用的函数,方便开发人员调用。(当然,说说简单,其实所谓的这些函数,大大方便了开发人员使用ajax技术。具体请参看ajax framework的官方介绍。)

特别说明:这个xmlhttpost方法改进了simple-ajax。在原基础上,将回调方法作为参数传递。


解释了原理性的内容之后,接下来,以一个模拟的应用场景,demo说明ajax的使用,以及它的主要应用场景。
模拟场景:
目录选择,即当选择一个目录的时候,需要显示这个目录下的所有子目录。

首先,我们来虚拟一个目录结构,如下:


那么,要实现目录选择,有三个方式:
1)页面初始化的时候,服务端将所有的目录信息都put到页面中。
   优点:选择操作简单,有了全部的目录信息,做选择操作,都可以使用js完成,无需和服务端进行交互
   缺点:当目录信息很大的时候,比如有上万个节点,整个目录信息有1m左右大小,那么要渲染这个页面,估计得20秒左右(视网速)
并且,很可能用户仅仅只要选择有限的几个节点就可以,比如上万个节点中选择6-7个节点,那么浪费太大了;
2)页面初始化的时候,服务端将当前需要的节点信息put到页面上,一旦有选择操作,重新刷新页面。
   优点:选择操作简单,对于节点信息,每次取需要的内容,不存在浪费现象
   缺点:每次都要刷新整个页面,除节点信息外,其他不变的东西都需要重新从服务端取,增加无谓的消耗。
3)页面初始化的时候,服务端将当前需要的节点信息put到页面上,一旦有选择操作,只刷新节点相关的内容;
   优点:每次只load需要的信息,局部刷新页面内容,不存在任何浪费现象
   缺点:需要异步请求数据,每次请求都需要和服务器交互,选择操作稍显复杂(异步请求,局部刷新)

通过这三种方式做对比,发现ajax主要适用的场景如下:
1)整体内容量大(几百k,几m,甚至几十m),而页面只需要其中一小部分信息即可;
2)数据显示,只涉及一个页面中部分数据信息的变动;

特别说明:至于使用ajax性能如何,需要对1,3两个情况做性能测试,权衡使用。

针对第三种方案,
首先需要一个取节点资源的url,
演示代码中,为了演示方便,使用php语言,而非使用主要语言java;
tree_node.php
<?php
$id =  $_GET['id']; 
if("1" == $id) {
  
echo("{\"id\":1,\"parentId\":-1,\"name\":\"1-1\",\"children\":[{\"id\":2,\"name\":\"2-1\"},{\"id\":3,\"name\":\"2-2\"},{\"id\":4,\"name\":\"2-3\"}]}");
else if("2" == $id) {
  
echo("{\"id\":2,\"parentId\":1,\"name\":\"2-1\",\"children\":[]}");
else if("3" == $id) {
  
echo("{\"id\":3,\"parentId\":1,\"name\":\"2-2\",\"children\":[]}");
else if("4" == $id) {
  
echo("{\"id\":4,\"parentId\":1,\"name\":\"2-3\",\"children\":[{\"id\":5,\"name\":\"3-1\"},{\"id\":6,\"name\":\"3-2\"}]}");
else if("5" == $id) {
  
echo("{\"id\":5,\"parentId\":4,\"name\":\"3-1\",\"children\":[]}");
else if("6" == $id) {
  
echo("{\"id\":6,\"parentId\":4,\"name\":\"3-2\",\"children\":[{\"id\":7,\"name\":\"4-1\"}]}");
else if("7" == $id) {
  
echo("{\"id\":7,\"parentId\":6,\"name\":\"4-1\",\"children\":[]}");
else {
  
echo("");
}
?>
该文件中,写死了目录结构(一般情况下,往往根据树对象,动态取得需要的节点)。


通过js,动态请求节点信息,部分刷新页面内容:
 <script type="text/javascript">
    
//模拟需求js
    var nodeSelect = function(text) {
      
var tree = toJsonObje(text);
      
var options = document.getElementById("tree").options;
      options.length 
= 0;
      options.add(
new Option("请选择","-1"));
      
if(tree == null) {
        
return;
      } 
else {
        
var children = tree.children;
        
for(i = 0; i < children.length; i++) {
          
var child = children[i];
          options.add(
new Option(child.name,child.id));
        }
        
if(tree.parentId != "-1") {
          options.add(
new Option("上一级",tree.parentId));
        }
      }
      document.getElementById(
"l").innerHTML = "当前位置:" + tree.name;
    }

    
function nodeSelectAjax(id) {
      
var TREE_NODE_URL = "tree_node.php";
      
var url = TREE_NODE_URL + "?id=" + id;
      xmlhttpPost(url,nodeSelect);
    }   
  
</script>
nodeSelectAjax,异步请求节点资源
nodeSelect,回调函数,根据请求信息,局部刷新页面


至于请求资源信息格式,任何方式都可以,只要client端能解析就行。
目前json格式,比较流行。
最后,附上java使用json库,生成json格式的方法:
JSONObject node = new JSONObject();
node.put(
"id"1);
node.put(
"parentId"-1);
node.put(
"name""1-1");
JSONArray children 
= new JSONArray();
JSONObject c1 
= new JSONObject();
c1.put(
"id"2);
c1.put(
"name""2-1");
JSONObject c2 
= new JSONObject();
c2.put(
"id"3);
c2.put(
"name""2-2");
children.put(c1);
children.put(c2);
node.put(
"children", children);
System.out.println(node.toString());



ajax demo
工程文件编码:utf-8
工程运行:http server with php supported
ubuntu firefox下测试通过


其他:
不知道是不是ie的bug,居然不支持 select.innerHTML = value的方式
只能通过select.options.add(new Option("content","value") 动态往select中添加选项。

posted on 2008-09-21 19:05 stone2083 阅读(1852) 评论(2)  编辑  收藏 所属分类: java

Feedback

# re: ajax原理简介以及简单demo演示 2013-07-23 09:07 saf sadfasd

asasdf  回复  更多评论   

# re: ajax原理简介以及简单demo演示[未登录] 2013-08-26 15:28 222

fdjgnd  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: