翻 译:www.ruby-china.cn 站长]
Prototype框架提供了非常容易和有意思的方法处理Ajax的调用,同时它也是浏 览器安全的 。除了简单的请求外,这个模块(指prototype里的Ajax)也能很聪明的处理从服务器返回 的javascript代码,并且提供了一个辅助的类不停的轮循。
Ajax的功能包含在了全局的Ajax对象里面。用于Ajax请求的 transport是xmlHttpRequest,它是从用户角度的对不同浏览器进行安全的抽象的结果。真正的请求是通过创建Ajax. Request对象的实例实现的。复制内容到剪贴板代码: new Ajax.Request('/some_url', { method:'get' });第一个参数是请求的地址,第二个是可选的哈希值。方法选项指定要使用的HTTP请求方法,默认是POST。
记住,由于安全的原 因(也就是防止跨站脚本攻击)Ajax请求只能被用在与包含这个Ajax请求页面相同的协议、主机与端口上。有些浏览器会允许任意的URL,但是你能不依 靠这个。
Ajax响应回调
Ajax请求默认是异步的,这也就意味着你必须要有回调函数能够处理返回的数据。回调方法 在发起请求的时候传给可选的哈希。复制内容到剪贴板代码:
new Ajax.Request('/some_url',这里两个回调函数传给了这个哈希值,分别表示成功与失败的警告。onSuccess和 onFailure根据返回的状态相应的被调用。第一个参数是原生的xmlHttpRequest对象,可以分别使用它的responseText和 responseXML属性。
{
method:'get',
onSuccess: function(transport){
var response = transport.responseText || "no response text";
alert("Success! \n\n" + response);
},
onFailure: function(){ alert('Something went wrong...') }
});
你可以把两个回调都定义,也可以是一个或者没有,这全由你来定。其它的可以用的回调函数还有:
onUninitialized,
onLoading,
onLoaded,
onInteractive,
onComplete and
onException.
他们都与xmlHttpRequest的传输的某一个状态有关系,除了在分发其它回调时出现异常后引起的onException外。
还 有可以得到的就是onXXX的回调。这里XXX是HTTP的返回状态,象200或者404。需要注意的是,如果用这种方法,你的onSuccess和 onFailure就不会被调用了。因为onXXX有更高的优先级,因为这样做的话,表示你知道你在做什么。
而 onUninitialized、onLoading、 onLoaded和onInteractive这些回调函数并没有完全的被所有的浏览器实现出来。通过我们避免使用它们。
参数与 HTTP方法
你可以将请求参数象一个参数属性一样传递。复制内容到剪贴板代码:
new Ajax.Request('/some_url', {
method: 'get',
parameters: {company: 'example', limit: 12}
});那么参数会以company=example&limit=12的形式发出。
你可以使用GET/POST中的任一种。但是需要注意的是GET的请求不应该导到致数据发生变化
。浏览器很少会缓存POST请求,但是它往往会缓存GET请求。
参数属性的一个重要的应用是用Ajax请求发送一个FORM的内容,Prototype已经给了你一个
帮助的方法,叫做Form.serialize:复制内容到剪贴板代码:
new Ajax.Request('/some_url', {
parameters: $('id_of_form_element').serialize(true)
});如果你需要发送自定义的HTTP请求头,你可以用requestHeaders项来实现。只要作为
一个哈希或者用一个扁平的数组传入名字—值对就可以了。如:['X-Custom-1', 'value',
'X-Custom-2', 'other value'].
如果由于某种原因,你必须POST一个自定义的POST体(没有参数来自于参数项)的请求,有
一个postBody项就是为了这个目的设的。要注意的时,如果你使用postBody,那么你传进来
的所有的参数都不会被发送,因为postBody有更高的优先级。这样做的时候,你应该是清醒
的。
对javascript返回值求值
有时应用程序发送javascript代码作为响应。如果这个返回的Contenty-Type与Javascript
的MIME的类型是一样的,那么Prototype将会自动eval()返回的代码。你如果没有需要的话
,就不用显式的处理这个响应。
还有可能就是这个响应是一个X-JSON的头,那他的内容就会被解析,保存成立个对象并发送
给这些回调函数,当成第二个参数:复制内容到剪贴板代码:
new Ajax.Request('/some_url', { method:'get',
onSuccess: function(transport, json){
alert(json ? Object.inspect(json) : "no JSON object");
}
});可以用这个函数来取比较重要的数据,以避免解析XML返回的损耗。JSON比XML要更快
(当然也更轻)。
全局响应者
这里有一个对象在每次Ajax请求时都会被调用:Ajax.Responders。你可以用他来注册回调
函数在任何一个Ajax.Request状态发生时被触发:复制内容到剪贴板代码:
Ajax.Responders.register({
onCreate: function(){
alert('a request has been initialized!');
},
onComplete: function(){
alert('a request completed');
}
});每个与xmlHttpRequest的传输状态匹配的回调都可以放在这里,再带上一个onCreate。
象这样的全局的跟踪请求在不少方面是很有用的:你可以把它们记录下来以用于调试或者抛
出一个异常处理,来通过用户可能的连接问题。
用Ajax.Updater来动态更新你的页面
开发者经常想通过Ajax请求来接收HTML的片段来更新文档的部分内容。通过Ajax.Request的
onComplete回调是相当容易的,但是如果是用Ajax.Update就会变得更加容易。
假设你的HTML文档中有以下代码:复制内容到剪贴板代码:
<h2>Our fantastic products</h2>
<div id="products">(fetching product list ...)</div>'products'容器是空的,你
想把Ajax的响应的HTML返回值放到这里。没有问题:复制内容到剪贴板代码:
new Ajax.Updater('products', '/some_url', { method: 'get' });这就是全部,没有别
的其它工作。变量与Ajax.Request是一样的。除了第一个位置上多了一个接收元素。
Prototype会通过Element.update()来神奇的把响应更新到容器。
如果你的HTML里还有内含的一些脚本,默认情况下会被过滤掉,为了让你的脚本被执行,你
必须在evalScripts选项上传入真值。
那如果有错误发生,服务器返回一个错误信息而不是HTML,那会怎么样?一般来讲,你不会
想插入错误到用户需要内容的地方。幸运的时,prototype提供了一个方法的解决办法:你
现在在第一个参数里传入以这种形式{ success:'products', failure:'errors' }表示两个
不同的容器的哈希值,而不只是原来那一个。那么成功的话,内容就会被放在success的容
器上,错误就会被放在failure容器上。通过使用这些特性,你的界面就会变得更加用户友
好。
你也可能不想覆盖当前容器中的内容,而是想把新的HTML加在最前或者最后面。很好,你完
全可以这样做。只要把要插入的对象当成是插入参数传递给Ajax就可以了:复制内容到剪贴
板代码:
new Ajax.Updater('products', '/some_url', {
method: 'get',
insertion: Insertion.Top
});Ajax.Updater就会使用给定的对象在容器('products')元素里对返回的HTML执行插入
。漂亮的手法!
用Ajax.PeriodicalUpdater自动执行请求
你发现Ajax.Updater很酷,但是你还想定时的执行他从服务器取数据?Prototype框架也有
这个东西。这个东西就是Ajax.PeriodicalUpdater,它基本上就是定时的运行Ajax.
Updater。复制内容到剪贴板代码:
new Ajax.PeriodicalUpdater('products', '/some_url',
{
method: 'get',
insertion: Insertion.Top,
frequency: 1,
decay: 2
});两个新的参数是频率与衰退。频率就是请求产生的间隔,用秒表示。这里它是1秒,表
示Ajax每分钟请求一次。默认的频率是2秒。我们的用户可能会对应用有这么好的响应程序
感到非常高兴,但是我们的服务器可能性会承受非常大的压力,如果用户一直长时间开着浏
览器的话。这也是为什么有decay这个选项的原因。这是一个因子,通过它,频率会在每次
得到相同的返回内容时被加倍。第一次可能是1秒,然后是2秒,然后是4秒,然后是8这样一
直下去。当然,如果这个服务器一直返回不同的数据,decay就不会起作用。这个因子只在
你的内容基本上不变化了,返回的数据也基本相同时才起作用。
将频率调低可以明显减轻服务器的负担,因为无用的请求次数会减少。你可以用这个因子在
监视服务器的负载,或者你可以传进1来完全关掉它(1是默认值)或者省略掉。