CGI::Ajax 模块中文入手指南(修正版)
CGI::Ajax 模块中文入手指南(修正版)
作者:JackyCheng (曾小成)
修改BY:NSNAKE 版权归原作者所有
发表:2006 年 6月 12 日
修改:2006.6.22
Ajax,由Jesse James Garrett创造,全称“Asynchronous JavaScript + XML”。Ajax目前被广泛用于更为动态、响应更灵敏的Web应用程序。该方法的关键在于对浏览器端的JavaScript、DHTML和与服务器异步通信的组合。如果使用得当,这种强大的力量可以使应用程序更加自然和灵敏,从而提升用户的浏览体验。
如果你还对Ajax没有一点感性的认识的话,这有个家伙可以给你点不同的感觉:http://www.dragonson.com/。另外,如果你有在Perlchina会员中心注册的话,你应该也感受到一点属于ajax的气息?
我们好像说远了,那么如何在Perl写的CGI中调用Ajax呢?幸运的是,我们并不用像其他程序员那样把XML和JavaScript学到吐血。Perl提供了一种简单的方法构建了一个十分强大的Ajax开发工具,这就是我们今天要介绍的CGI::Ajax模块。
l 安装
请原谅我的啰嗦,因为的确还有好多兄弟不知道如何安装一个简单的模块。Linux下安装模块最为快捷的方法自然是CPAN,于是请你在命令行下输入($只是为了提醒你在命令行下,除此之外,他没有其他意义):
$ perl -MCPAN -e 'install CGI::
之后我们就可以座在桌子前轻松的喝茶了。在windows下,我们需要进入命令行,输入:
$ ppm
$ install CGI::Ajax
稍等一下,我们就可以得到安装成功的提示。
l 一次对于Ajax的旋风旅行
打开你的编辑器,输入如下内容,然后放到你服务器的根目录下,运行它看看得到了什么?
#! /usr/bin/perl -w
use strict;
use CGI; # 如果用其他的CGI编解码模块也是可以的
use CGI::Ajax;
my $cgi = new CGI;
my $ajx = new CGI::Ajax( 'exported_func' => \&sub );
print $ajx->build_html( $cgi, \&Show_HTML);
sub sub {
my $input = shift;
my $output = $input . "被输出!";
return( $output );
}
sub Show_HTML {
my $html = qq~
<HTML>
<BODY>
请随便输入: <input type="text" name="val1" id="val1" onkeyup="exported_func( ['val1'], ['resultdiv'] );">
<br><div id="resultdiv"></div>
</BODY>
</HTML>~;
return $html;
}
你不用惊叹于我是如何写出这样如此精湛又简洁的程序,因为,他的确不是我写得。你可以在 http://www.perljax.us/demo/ 找到更多。
l 第一个实例的解读
庆幸于我们的眼力还没到需要别人捐献角膜的地步,上面的程序原来是没有行号的(你要知道我们弄成这样全是你害的,如果不是为了让你顺利运行,我们才不去行号呢)。那就请你现在动起你的手指来。
第三行use CGI::Ajax; 该行告诉PERL我们现在要载入CGI::Ajax这个模块,如果不载入的话,后面的代码可是会出错的!
CGI::Ajax模块允许我们在成功载入页面并触发一个相应的指令后,调用Perl 的子程序。于是在第5行,我们看到如下的代码:
my $pjx = new CGI::Ajax( 'exported_func' => \&perl_func );
该行声明一个CGI::Ajax对象并使perl_func这个子程序被对象里面的exported_func(我们先不管它是什么,先往下看)所引用,此后当页面内调用exported_func时,该子程序将会被执行。
现在我们看到第22行,exported_func被一个事件绑定,当事件触发时,那么Perl就会先找到exported_func,然后再执行对应的perl_func。由此我们可以得出,exported_func只是起一个中间量作用,用于连接perl的子程序及页面事件。
注意,exported_func在这只是个名字而已,并没有什么特殊。于是你可以把他叫做dog、pig,甚至小泉纯一郎(要知道自从Perl支持了Unicode之后,用什么作为变量名几乎都是可能的,不过不建议这样做,就如MYSQL支持中文表名但我想没几个人会用一样吧)。同样,我们也可以同时使用更多的“对应”,例如:
my $pjx = new CGI::Ajax( 'ec' => \&dog,'pz' => \&pig);
确立对应之后我们所做的就是建造完整的HTML代码,最后,在第七行,我们通过build_html()来调用CGI模块输出完整的代码。(实际上build_html()这个函数可不简单,我们后面再细说)
l 更为高级的实例:在页面内执行外部程序
其实在Ajax中更常用的功能好像是调用一个外部程序,然后产生某些结果再返回页面(nsnake:比如做无刷新显示数据的页面)。就好像PerlChina会员系统的注册页面,你可以先去这里玩一下( http://member.perlchina.org/register,nsnake:或者163的邮箱也是很好的例子 ),当然,请不要搞垮这个智慧的系统,如果他们的系统工程师愤怒起来,我的后果是很惨重的(nsnake:好像也没你说的那容易夸掉的吧!)。
就像你看到的那样,当你输入一些资料时(nsnake:比如当你输入用户名后继续填写下面的信息),此时事件开始执行(nsnake:AJAX的数据提交分同步和异步执行,具体意思大家可以搜索下,这里的信息提交应该是异步的),此时你的注册名其实已经被提交到后台进行数据检测并返回结果,而此时前台会通过JS脚本接受这个返回的结果并显示在页面上。(nsnake:不用担心不会编写JS脚本的问题,当你使用这个模块的时候它已经把一切都给你安排好的)
整个过程看似与第一个实例大致相同,只是第一个程序调用的是Perl子进程,而第二个程序调用的是外部的程序(nsnake:也就是把数据提交到另外的一个页面并交个它去处理)。不用担心这会很复杂,因为我们只需把最开始的 'exported_func' => \&perl_func里面的perl_func子程序换成我们需要的页面即可。
#! /usr/bin/perl -w
use strict;
use CGI; # 如果用其他的CGI编解码模块也是可以的use CGI::
my $cgi = new CGI;
my $url = 'scripts/other_script.pl';
my $pjx = new CGI::Ajax( 'external' => $url );
print $pjx->build_html( $cgi, \&Show_HTML);
sub Show_HTML {
my $html = qq~
<HTML>
<BODY>打点有意思的: <input type="text" name="val1" id="val1"><br><input type="text" name="val2" id="val2" onkeyup="external(['val1',"val2"],['resultdiv'];"><br>
<div id="resultdiv"></div></BODY></HTML>~;
return $html;
}
当外部程序被调用时,它将得到一个名为 'args' 的数组,里面涵盖了所有在原程序中被指定输出的数据。
my @input = $cgi->param('args');
$input[0];
$input[1];# 可能还有更多,等等等等.......
l 更加丰富的传递方法
事实上,我们每个人都必须个性化,否则世界也将不称之为世界了。于是总有些程序会指定一些特别的参数让你来传递,例如有一个外部程序xx.cgi只接受名为cook和meal的数据,那我们怎么办呢?这里有一种方法:
onClick="exported_func(['args__42'],['resultdiv']);"
这时你就得到了类似执行于script.pl?args=42这样的结果。
另外有些时候我们只想传递变量而不是页面中的元素,那么你应该这样做:
onClick="exported_func(['args__$input1','args__$input2'],['resultdiv']);"
如果你想收到从一个外部的程序传来的更多组数据,那么你需要把那些数据用“__pjx__”串连起来。
精力的问题,我们不能说太多(事实上如果全都说完应该可以写本书了),但是这些对于构建一个基本的Ajax系统已经足够多了。 That's all。希望这篇文章对你有用。
l 你不知道但不会伤害你的东西,很多
如果你的后台接受程序只能接受GET、POST传给数据,你可以使用下面的方法来进行GET或POST方式的提交(nsnake:这对于ASP编写的程序很重要,因为它接受GET或POST的函数是不一样的):
onClick="exported_func(['input1'],['result1'],'GET');" onClick="exported_func(['input1'],['result1'], 'POST');"
有时候客户端对目标地址已经有了缓存,于是我们此时很难得到我们想要的结果。这里有一种方法可以使客户端的缓存失效:
onClick="exported_func(['input1','NO_CACHE'],['result1']);"
精力的问题,我们不能说太多(事实上如果全都说完应该可以写本书了),但是这些对于构建一个基本的Ajax系统已经足够多了。 That's all。希望这篇文章对你有用。我们会在接下来的几个版本中持续更新。
附注:此文章大部分实例取自CGI::Ajax模块附带文档及演示。