2.1. The Old-Fashioned Way
2.1. The Old-Fashioned Way |
首先,我们来看一个Ajax的简单实例:点击一个链接,使用XMLHttpRequest呈现一个从服务器返回的回应。在这个实例中不使用Prototype或者是Rails JavaScript辅助器。
有时候,人们常常觉得使用XMLHttpRequest技术非常复杂,但是下面通过一些小练习和一组新概念,你会觉得这个东西并不像人们说的那样。
2.1.1. Starting a Project(创建一个项目)
在终端下输入:
rails ajaxonrails
cd ajaxonrails
ruby script/server
cd ajaxonrails
ruby script/server
打开浏览器[url]http://localhost:3000[/url]会看到rails的欢迎画面。再打开一个终端,创建一个名字叫Chapter2Controller的控制器和一个myaction的action(一个终端在运行http服务,你这时可以另外打开一个终端)
script/generate controller chapter2 myaction
myaction.rhtml中添加下面的代码
<p><a href="#" onclick="alert('Hello !');">Inline alert( )</a></p>
这里创建了一个段落<p></p>这里有一个基本的链接,但是没使用通常使用的href属性,而使用了onclick,这个onclick后面提供了一个要运行的Javascript片段。下面刷新浏览器,点击这个链接,会看到下图的效果
在onclick属性里面加上一些代码,马上就会变得复杂起来,下面我们修改这段代码来实现一个新的javascript功能:
<p><a href="#" onclick="customAlert( );">Call custom function</a></p>
<script type="text/javascript">
function customAlert( ) {
alert('Hello from a custom function.');
}
</script>
<script type="text/javascript">
function customAlert( ) {
alert('Hello from a custom function.');
}
</script>
再刷新浏览器,看看会发生什么?结果本质上跟上面的是一样的。
好了,热身完毕。下面做一下Ajax的练习(要记得,我们在这张结束之前都是在窥探Javascript底层的东西,Rails框架会隐藏很多javascript的复杂性)首先,我们需要定义一个新的action,名字myresponse.再新建一个myresponse.rhtml,里面的代码:
Hello from the server.
回到myaction.rhtml,添加一些HTML和Javascript进去:
<p><a href="#" onclick="serverSideAlert( );">Call server-side function</a></p>
<script type="text/javascript">
function serverSideAlert( ) {
var request = new XMLHttpRequest( );
request.open('get', '/chapter2/myresponse', false);
request.send(null);
alert(request.responseText);
}
</script>
<script type="text/javascript">
function serverSideAlert( ) {
var request = new XMLHttpRequest( );
request.open('get', '/chapter2/myresponse', false);
request.send(null);
alert(request.responseText);
}
</script>
再次打开[url]http://localhost:3000/chapter2/myaction[/url],,点击新链接,如果一切顺利,会出现如下图所示的结果:
这里需要特别说明下,如果是IE浏览器而版本是IE7以下,运行会出现问题(后面会讲解这个问题)
现在,我们取得了一点小成就。为了让自己相信,来看看终端中(运行script/server)的提示信息,每次你点击Ajax的链接时,就会有这些信息出现:
Processing Chapter2Controller#myresponse [GET] Parameters: {"action"=>"myresponse", "controller"=>"chapter2"} Completed in 0.00360 (278 reqs/sec) | Rendering: 0.00027 (7%) | 200 OK [[url]http://localhost/chapter2/myresponse[/url]]
现在这个例子中最大的问题就是它在最流行的浏览器IE6下不能工作。这是因为微软执行XMLHttpRequest时将其作为一个ActiveX对象。(实际上两者都依赖于IE的版本),而ActiveX对象必须以一种不同的方式来创建。为了包含这种情况,我们需要创建一个小功能来实现:
<p><a href="#" onclick="IEAlert( );">Call server(IE-safe)</a></p>
<script type="text/javascript">
function IEAlert( ) {
function getRequestObject( ) {
try { return new XMLHttpRequest( ) } catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {}
return false
}
var request = getRequestObject( );
request.open('get', '/chapter2/myresponse', false);
request.send(null);
alert(request.responseText);
}
</script>
<script type="text/javascript">
function IEAlert( ) {
function getRequestObject( ) {
try { return new XMLHttpRequest( ) } catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {}
return false
}
var request = getRequestObject( );
request.open('get', '/chapter2/myresponse', false);
request.send(null);
alert(request.responseText);
}
</script>
这里没有直接创建一个XMLHttpRequest对象,而使用了编写了一个getRequestObject(),在方法体里利用try(一个Javascript的声明用来捕获异常并且阻止异常发生)涵盖了可能出现的情况。(这个例子也给开发者提供了一个思路,在function中定义另一个function)
到目前为止,我们其实撒了个小谎,因为前面的Ajax不是异步调用的,request.open()方法中第三个变量决定了不管是不是异步的调用,它的值一直都是false,因此request.send()当请求没有返回之前,让Javascript解释器执行那一行。为了让调用产生异步效果,我们必须重新对一些东西进行整理,在myaction.rhtml中加入下面的代码:
<p><a href="#" onclick="asyncAlert( )">Call async server-side</a></p>
<script type="text/javascript">
function asyncAlert( ) {
function getRequestObject( ) {
try { return new XMLHttpRequest( ) } catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {}
return false
}
var request = getRequestObject( );
request.open('get', '/chapter2/myresponse');
request.onreadystatechange = function( ) {
if(request.readyState==4) alert(request.responseText);
}
request.send( );
}
</script>
<script type="text/javascript">
function asyncAlert( ) {
function getRequestObject( ) {
try { return new XMLHttpRequest( ) } catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {}
return false
}
var request = getRequestObject( );
request.open('get', '/chapter2/myresponse');
request.onreadystatechange = function( ) {
if(request.readyState==4) alert(request.responseText);
}
request.send( );
}
</script>
本文转自 fsjoy1983 51CTO博客,原文链接:http://blog.51cto.com/fsjoy/90900,如需转载请自行联系原作者