JAVA

人生若只如初见,何事秋风悲画扇。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  50 随笔 :: 25 文章 :: 157 评论 :: 0 Trackbacks

  这二天用prototype.js中的ajax.request做了些东西,闲时看了下源码,体会如下:

  在用AJAX部分前,有如下一些函数得了解一下:
  Class变量

var  Class  =   {
  create: 
function ()  {
    
return   function ()  {
      
this .initialize.apply( this , arguments);
    }

  }

}


  initialize相当于构造器,和java的构造器一样,可以自定义为带参数性质的。prototype中很多对象都是用它来创建的,ajax也不例外。

Try.these() 方法

var  Try  =   {
  these: 
function ()  {
    
var  returnValue;

    
for  ( var  i  =   0 ; i  <  arguments.length; i ++ {
      
var  lambda  =  arguments[i];
      
try   {
        returnValue 
=  lambda();
        
break ;
      }
  catch  (e)  {}
    }


    
return  returnValue;
  }

}


  它使得实现当你想调用不同的方法直到其中的一个成功正常的这种需求变得非常容易, 他把一系列的方法作为参数并且按顺序的一个一个的执行这些方法直到其中的一个成功执行,返回成功执行的那个方法的返回值。
  ajax就是通过它得到一个可以跨borswer的xmlhttp的:

var  Ajax  =   {
  getTransport: 
function ()  {
    
return  Try.these(
      
function ()  { return   new  ActiveXObject('Msxml2.XMLHTTP')} ,
      
function ()  { return   new  ActiveXObject('Microsoft.XMLHTTP')} ,
      
function ()  { return   new  XMLHttpRequest()}
    ) 
||   false ;
  }


  activeRequestCount: 
0
}


Object.extend方法:

Object.extend  =   function (destination, source)  {
  
for  (property  in  source)  {
    destination[property] 
=  source[property];
  }

  
return  destination;
}


  顾名思义,可正扩展了一个对象属性列表。这样说可能不太明白,结合Ajax再下就清楚了,如下,

Ajax.Base.prototype  =   {
  setOptions: 
function (options)  {
    
this .options  =   {
      method:       'post',
      asynchronous: 
true ,
      parameters:   ''
    }

    Object.extend(
this .options, options  ||   {} );
  }
,
   
}


  可以看到在prototype中用ajax的时候,它的options默认有三个,默认值如上所示。这里可以通过以下方式来改变其默值(Ajax.Request的用法,呆会儿再看):

var  pars  =  'method = update & mbid = 917 ';
var  my  =   new  Ajax.Request(
 uri, 
 
{
  method: 'post',
  parameters: pars,
  asynchronous: 
false ,
 }
);
}

  这时有个问题可能不太好处理,假如想增加其它参数,怎么知道我所增加的参数是否符合prototype呢?确实!比如我想通过send方法传一段数据到后台,该用什么参数呢?在prototype中有如下代码:

var  body  =   this .options.postBody  ?   this .options.postBody : parameters;
this .transport.send( this .options.method  ==  'post'  ?  body :  null );


  可以看到应该是postBody,对于prototype中的参数以及其所代表的意义我想还是得通过源文件一个个的找。作者并没有初始一个集合(废话,不然也不要Object.extend方法了)。我觉得这个地方有待改进... ...

  在send时方法一定要用post才能生效,这个时候parameters就会失效了,源码如下:

if  ( this .options.method  ==  'get'  &&  parameters.length  >   0 )
        
this .url  +=  ( this .url.match( / \ ?/ ?  ' & ' : ' ? ')  +  parameters;


  所以假如后台一定要一个parameter的话,比如若用到Struts的LookupDispatchAction就很可能要一个method参数。这时应该直接放到uri中去,最后要注意的一点就是用post的时候,一定要将响应头设置成Content-type==application/x-www-form-urlencoded. 好在prototype已经考虑到了这点:

this .setRequestHeaders(); // 其具体代码可以看源文件
var  body  =   this .options.postBody  ?   this .options.postBody : parameters;
this .transport.send( this .options.method  ==  'post'  ?  body :  null );


  在这儿我说一下我在使用ajax过程中遇到乱码的解决方法:
  从C到S头端时,在S端接到的是乱码解决分析过程。首先要明白AJAX内部是以utf-8来编码传输数据的。我们在页面所看到的数据都是按照我们自己预定的字符集解码所得到的。OK,现在假设我们在S端收到了来自C端的DATA为乱码,在C端(不管你的WEB页面是用什么编码方式)AJAX在其传输中把所传输的数据解码成UTF-8格式,到了S端后,我可能对所有请求方式都过滤编码,比如有如下设置:

< filter >
  
< filter-name > encodingFilter </ filter-name >
  
< filter-class >
   com.CharacterEncodingFilter
  
</ filter-class >
  
< init-param >
   
< param-name > encoding </ param-name >
   
< param-value > GBK </ param-value >
  
</ init-param >
  
 
</ filter >


  所以我们在S端看到的是将以UTF-8编码过的数据再以GBK解码后所得到的数据,这样乱码就出来了。所以解决也很简单,交其重新以自己的方式编码就OK了
  new String(str.getBytes("gbk"),"utf-8");

  同样的道理,假如在C端碰到的是乱码,那么在S端返回数据前将数据以UTF-8的格式传输
  src.getBytes("UTF-8")

  ajax.request中对事件的响应:
  首先我们得在请求初始化中加入响应状态与自定义函数:

var  my  =   new  Ajax.Request(
   url, 
   
{
    method: 'get',
    parameters: pars,
    asynchronous: 
true ,
    onComplete: showResponse
   }
);


它初始化了一个ajax事件的集合

Ajax.Request.Events  =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];


  这五个状态正好对应五个readystate,ajax的五个readystate分别如下:
  0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)
  1 (初始化) 对象已建立,尚未调用send方法
  2 (发送数据) send方法已调用,但是当前的状态及http头未知
  3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,
  4 (完成) 数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据

然后根据status(点这儿可以下载查看ajax参考资料,查看其所有属性)来触发指定事件,触发代码:

onStateChange:  function ()  {
    
var  readyState  =   this .transport.readyState;
    
if  (readyState  !=   1 )
      
this .respondToReadyState( this .transport.readyState);
  }

 respondToReadyState: 
function (readyState)  {
    
var  event  =  Ajax.Request.Events[readyState];


再次可以看到正好事件集合与readyState正好对应来调用,而通过以下来调用WEB自定义函数showResponse()

try   {
     
      (
this .options['on'  +  event]  ||  Prototype.emptyFunction)(transport, json);
      Ajax.Responders.dispatch('on' 
+  event,  this , transport, json);
    }
  catch  (e)  {
      
this .dispatchException(e);
    }


 未完,待续...

posted on 2006-07-21 16:47 Jkallen 阅读(33247) 评论(20)  编辑  收藏 所属分类: AJAX其它开源

评论

# re: prototype.js之ajax.request学习(一) 2006-07-22 20:46 TiGERTiAN
prototype有一定局限性,比如,我需要调用一个函数getArticleList()里面有很多参数:新闻条数,标题长度,是否打开新窗口等等,用这个框架的话,我不知道怎么把这些参数传递出去,因为他只有一个
var my = new Ajax.Request(
url,
{
method: 'get',
parameters: pars,
asynchronous: true ,
onComplete: showResponse
} );
而showResponse的默认参数只有一个就是originalRequest,请问下水有好的办法解决这个问题  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 08:31 蓝天
showResponse 中其实是有二个参数的,看源代码就知道
还有一个是跟json 头有关

而第一个刚是在ajax.request中得到的xmlhttp,你可以通过此参数得到到后台传来的text or xml格式的内容,然后再处理就是了

新闻条数,标题长度,是否打开新窗口...这些东西你以自己的方式组织好,到了前台再展开就可以了.  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 08:37 TiGERTiAN
有个问题,例如我这个getArticleList函数在一个页面又多次不同调用,那我肯定有多个不同xmlHttp对象,也就是说
function getArticleList(x,y,z)
{
//先建立xmlHttp对象并请求数据
//然后获得了数据得到反应,我肯定需要把x,y,z传给一个用来处理数据的getList,但是如果我用prototype的话,getList就只有那两个参数,我如何把我所需要的x,y,z一并传给getList呢? 这就是我的疑问
}  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 14:20 蓝天
getList 这个你是指后台还是指在前台呢?

假如是指在后台的的话那么你在用ajax.request的时候直接将三个数据放到prameter上(要是数据大可以考虑用post通过send来传输)来传送到后台.

要是指前台函数的话,应该就是JS函数了.那么你在后台先封装好x,y,z这三个数据(可以通过XML格式以及其它广西格式),然后将它们放到流里,到前台xmlHttp可以直接取了.

你不可能(也没必要)把showResponse ()里面加帮加三个参数. 这些都在prottype中预先定义好的

应该明白了吧?  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 14:30 TiGERTiAN
我的意思你可能没有看明白,我的意思是我需要用js控制1.新闻的显示条数,2.标题长度(同时在超链接的title属性中要显示全称,所以就不可以用后台直接生成好限制长度的新闻标题),还有我要控制的3.表格CSS,还有就是超链接是否弹出窗口等等很多参数,我需要做成一个函数,让多个不同样式不同需要的新闻栏目去调用这个函数,那么就要传递不同的参数也就是说,在首页里面我可能这样调用
最新新闻getArticleList(x1,y1,z1);
热点新闻getArticleList(x2,y2,z2);
招聘信息getArticleList(x3,y3,z3);
其它栏目以此类推
getArticleList这个函数我主要用来创建xmlHttp并获取数据存放在xmlHttp中,当onreadystatechange的时候我调用getList函数来处理xmlHttp,这样有个问题就来了,我那些新闻条数,标题长度等的参数也要一并传入getList中,但prototype之可以有两个参数,那我其它参数如何传递如getList呢?需要注意不可以有全局变量,否则我怕会出现参数调用错误也就使x1可能还在用就被x2给替换了,不知道如何解决
  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 14:50 蓝天
最新新闻getArticleList(x1,y1,z1);
热点新闻getArticleList(x2,y2,z2);
招聘信息getArticleList(x3,y3,z3);

这个里面的x*, y*, z* 都是从后台取来的吗?

假如是:
将它们封到xmlhttp中去,在JS中解析出来,再调用原来的代码
getArticleList(xmlhttp){
x*= //throuth xmlhttp do sth
y*= //throuth xmlhttp do sth
z*= //throuth xmlhttp do sth
//do origiral code ....
};  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 14:55 TiGERTiAN
x,y,z是getArticleList的参数,使我在某个静态页面里面自己写的,用来控制页面显示格式的,如新闻的条数,标题长度,是否显示时间等等,不是从后台得到的。你再看一下我上一边回帖。如何把这些参数也传递进showResponse呢?  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 17:10 蓝天
if so
那你直接到 showResponse 里面执行完xmlhttp的相关操作后再调用你想要的
getArticleList好了啦  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 21:35 TiGERTiAN
这个很难办到,你怎样在调用完showResponse之后才来控制输出?那些参数怎么传进去?  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 22:17 blue

showResponse (){
//with xmlhttp do something u want to do
getArticleList(x1,y1,z1); //如果点的是最新新闻,里面就放最新新闻的相关参数。其它也一样,也许我想的跟你不同,太简单了
}

这儿都成BBS了哈...   回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-24 22:20 TiGERTiAN
a simple question...Where are these x,y,z from???你怎么传进来这些x,y,z?我说过不能用全局,否则可能会错乱  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-07-31 14:17 看看
ajax太好了  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-08-28 13:17 watson
后台怎么写啊!!!???

我网点上搜到的全是前台,难道后台不用写么 ???

谢谢!!!!  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-08-28 17:26 草好
[item]GM之拳[/item]  回复  更多评论
  

# re: prototype.js之ajax.request学习(一) 2006-08-28 20:35 蓝天
后台跟平时WEB页面传一样的写  回复  更多评论
  

# re: prototype.js之ajax.request学习笔记(一) 2006-10-21 22:48 暗暗
说清楚点好吗?????????????  回复  更多评论
  

# 蓝天 你根本没明白 TiGERTiAN 问的问题 2006-12-05 10:14
请问 TiGERTiAN , 你遇到的问题解决了么?  回复  更多评论
  

# re: prototype.js之ajax.request学习笔记(一) 2007-05-10 15:38 Jidan
prototype.js是公用的吗?  回复  更多评论
  

# re: prototype.js之ajax.request学习笔记(一) 2008-03-05 16:17 zhxp
传参的问题搞定..
Ajax.Request.prototype.tableName = this.tableName;
var myAjax = new Ajax.Request(this.url,{method: 'get', parameters: this.parmeter, onSuccess:function(originalRequest){
var data = new Data(eval(originalRequest.responseText),myAjax.tableName)
data.render();
}});  回复  更多评论
  

# re: prototype.js之ajax.request学习笔记(一) 2009-06-01 22:25 aeon
@TiGERTiAN

function processRequest(url) {
new Ajax.Request(
url,
{
method: 'get',
parameters: pars,
asynchronous: true ,
onComplete: showResponse
}
);
}

function showResponse(req) {
alert(req.responseText);
}
  回复  更多评论
  


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


网站导航: