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

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中添加选项。

你可能感兴趣的:(ajax原理简介以及简单demo演示)