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属性。
你可以把两个回调都定义,也可以是一个或者没有,这全由你来定。其它的可以用的回调函数还有:
onUninitialized,
onLoading,
onLoaded,
onInteractive,
onException.
他们都与xmlHttpRequest的传输的某一个状态有关系,除了在分发其它回调时出现异常后引起的onException外。
还有可以得到的就是onXXX的回调。这里XXX是HTTP的返回状态,象200或者404。需要注意的是,如果用这种方法,你的onSuccess和onFailure就不会被调用了。因为onXXX有更高的优先级,因为这样做的话,表示你知道你在做什么。
而onUninitialized、onLoading、 onLoaded和onInteractive这些回调函数并没有完全的被所有的浏览器实现出来。通过我们避免使用它们。
参数与HTTP方法
你可以将请求参数象一个参数属性一样传递。
new Ajax.Request('/some_url', {
那么参数会以company=example&limit=12的形式发出。
你可以使用GET/POST中的任一种。但是需要注意的是GET的请求不应该导到致数据发生变化。浏览器很少会缓存POST请求,但是它往往会缓存GET请求。
参数属性的一个重要的应用是用Ajax请求发送一个FORM的内容,Prototype已经给了你一个帮助的方法,叫做Form.serialize:
new Ajax.Request('/some_url', {
如果你需要发送自定义的HTTP请求头,你可以用requestHeaders项来实现。只要作为一个哈希或者用一个扁平的数组传入名字—值对就可以了。如:['X-Custom-1', 'value', 'X-Custom-2', 'other value'].
如果由于某种原因,你必须POST一个自定义的POST体(没有参数来自于参数项)的请求,有一个postBody项就是为了这个目的设的。要注意的时,如果你使用postBody,那么你传进来的所有的参数都不会被发送,因为postBody有更高的优先级。这样做的时候,你应该是清醒的。
对javascript返回值求值
有时应用程序发送javascript代码作为响应。如果这个返回的Contenty-Type与Javascript的MIME的类型是一样的,那么Prototype将会自动eval_r()返回的代码。你如果没有需要的话,就不用显式的处理这个响应。
还有可能就是这个响应是一个X-JSON的头,那他的内容就会被解析,保存成立个对象并发送给这些回调函数,当成第二个参数:
new Ajax.Request('/some_url', { method:'get',
可以用这个函数来取比较重要的数据,以避免解析XML返回的损耗。JSON比XML要更快(当然也更轻)。
全局响应者
这里有一个对象在每次Ajax请求时都会被调用:Ajax.Responders。你可以用他来注册回调函数在任何一个Ajax.Request状态发生时被触发:
Ajax.Responders.register({
});
每个与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选项上传入真值。
o
那如果有错误发生,服务器返回一个错误信息而不是HTML,那会怎么样?一般来讲,你不会想插入错误到用户需要内容的地方。幸运的时,prototype提供了一个方法的解决办法:你现在在第一个参数里传入以这种形式{ success:'products', failure:'errors' }表示两个不同的容器的哈希值,而不只是原来那一个。那么成功的话,内容就会被放在success的容器上,错误就会被放在failure容器上。通过使用这些特性,你的界面就会变得更加用户友好。
你也可能不想覆盖当前容器中的内容,而是想把新的HTML加在最前或者最后面。很好,你完全可以这样做。只要把要插入的对象当成是插入参数传递给Ajax就可以了:
new Ajax.Updater('products', '/some_url', {
new Ajax.Updater('products', '/some_url', {
new Ajax.PeriodicalUpdater('products', '/some_url',
两个新的参数是频率与衰退。频率就是请求产生的间隔,用秒表示。这里它是1秒,表示Ajax每分钟请求一次。默认的频率是2秒。我们的用户可能会对应用有这么好的响应程序感到非常高兴,但是我们的服务器可能性会承受非常大的压力,如果用户一直长时间开着浏览器的话。这也是为什么有decay这个选项的原因。这是一个因子,通过它,频率会在每次得到相同的返回内容时被加倍。第一次可能是1秒,然后是2秒,然后是4秒,然后是8这样一直下去。当然,如果这个服务器一直返回不同的数据,decay就不会起作用。这个因子只在你的内容基本上不变化了,返回的数据也基本相同时才起作用。
将频率调低可以明显减轻服务器的负担,因为无用的请求次数会减少。你可以用这个因子在监视服务器的负载,或者你可以传进1来完全关掉它(1是默认值)或者省略掉。
https://compdoc2cn.dev.java.net/prototype/html/prototype.js.cn.html#options_reference