前言:
wap是无线应用程序通讯协议(wireless application protocal的简称。wap 定义了一套由 xml标准延伸而来的标记语言,称为「无线标记语言wireless markup language, wml」),专门用来将准备传送给无线上网设备的内容进行编码。与html用来定义资料在一般网络浏览器上面的显示与动作方式的标记语言那样,wml是用来定义资料如何在无线上网设备上显示与动作的标记语言。wap与wml技术对于提供信息给客户与在办公室外工作的员工来说,都是相当适合的技术。在这里我将会通过几个简单的例子向大家介绍在perl程序语言在wap网站的的应用,使你对perl语言有一个更深入的认识。
注:本文部份资料译自comprehensive perl archive.network网站(网址:http://cpan.org/)本文适用于对xml和http有一定认识的读者。
1、编写动态cgi程序
由于 wap 同样使用http通讯协议,因此你可以依照为一般网络浏览器开发动态内容程序相同的设计策略来为无线上网工具开发应用程序。事实上,你甚至可以说两者的开发流程除了一些特定的细节部分以外,大致上都是相同的。首先,一般的网络浏览器接受的内容类型(http 通讯中的 content-type 表头)信息为 text/html,而无线上网的客户端程序则要求你的程序送出 text/vnd.wap.wml 做为内容类型的值。其次,由于传送给无线上网客户端程序的文件事实上是一个xml文件,因此你必须将 xml 文件类型宣告字符串一并送出。只要你注意以上两点,那么你便可以开始传送你的内容了。下面是一个很简单的传送 wml 文件的 cgi 程序。
#!/usr/bin/perl
print "content-type: text/vnd.wap.wml\n\n";
print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
print "<!doctype wml public \"-//wapforum//dtd wml 1.1//en\"
\"http://www.wapforum.org/dtd/wml_1.1.xml\">\n";
print "<wml>\n";
print " <card id='card1'>\n";
print " <p>欢迎来到我的wap网站!</p>\n";
print " </card>\n";
print "</wml>\n";
这个例子演示了如何在wml文件里面传送正确的http与xml表头信息给浏览器。由于我们传送的实际上是一个xml文件,因此在输出资料的时候请记得要遵循正确的语法与格式。一般的网络浏览器对于内容类型或者表头宣告等信息的语法和格式都非常宽容,然而wap客户端程序却非如此。
上面这个程序所输出的内容虽然是实时产生的,但是它在任何状况下送出的内容都是完全相同的,互动性不是很好。为了解决这个问题,你可以通过cgi函式库来读取客户端送入的资料,并且根据这些传入的资料来实时建立新的内容传送回客户端。wml 本身被设计成尽可能内容能实时产生越好,这样的设计让页面中的每一个 deck 元素可以不需要送出新的 http 请求给服务器便可以从一个card元素移动到另一个card 元素。不过这也意味着你在接收从 wml 文件传入的资料的时候要格外小心,必须确认最后一个card元素确实有传送所有的变量到服务器端才行。在下面的范例程序会从客户端读取来自不同card元素所送出的参数,并且将这些参数传送给服务器,然后据此建立一个新的deck元素。
#!/usr/bin/perl
use cgi;
print "content-type: text/vnd.wap.wml\n\n";
print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
print "<!doctype wml public \"-//wapforum//dtd wml 1.1//en\"
\"http://www.wapforum.org/dtd/wml_1.1.xml\">\n";
my $input = new cgi;
if ($input->param("completed")) {
print "<wml>\n";
print " <card id='card1'>\n";
print " <p>welcome to my dynamic wireless cgi\n</p>\n";
print " <p>your name is: ";
print " ".$input->param("first_name")." ";
print " ".$input->param("middle_name")." ";
print " ".$input->param("last_name")." ";
print " </p>\n";
print " </card>\n";
print "</wml>\n";
} else {
print "<wml>\n";
print " <card id=\"read_first_name\">\n";
print " <do type=\"accept\" label=\"next\">\n";
print " <go href=\"#read_middle_name\"/>\n";
print " </do>\n";
print " <p>please enter your first name</p>\n";
print " <p><input name=\"first_name\"
emptyok=\"false\"/></p>\n";
print " </card>\n";
print " <card id=\"read_middle_name\">\n";
print " <do type=\"accept\" label=\"next\">\n";
print " <go href=\"#read_last_name\"/>\n";
print " </do>\n";
print " <p>please enter your middle name</p>\n";
print " <p><input name=\"middle_name\"
emptyok=\"false\"/></p>\n";
print " </card>\n";
print " <card id=\"read_last_name\">\n";
print " <do type=\"accept\" label=\"next\">\n";
print " <go href=\"#finish\"/>\n";
print " </do>\n";
print " <p>please enter your last name</p>\n";
print " <p><input name=\"last_name\"
emptyok=\"false\"/></p>\n";
print " </card>\n";
print " <card id=\"finish\">\n";
print " <do type=\"accept\" label=\"continue\">\n";
print " <go method=\"get\" href=\"?\">\n";
print " <postfield name=\"first_name\"
value=\"\$first_name\"/>\n";
print " <postfield name=\"middle_name\"
value=\"\$middle_name\"/>\n";
print " <postfield name=\"last_name\"
value=\"\$last_name\"/>\n";
print " <postfield name=\"completed\"
value=\"true\"/>\n";
print " </go>\n";
print " </do>\n";
print " <p>deck summary:</p>\n";
print " <p>first name: \$first_name</p>\n";
print " <p>mid name: \$middle_name</p>\n";
print " <p>last name: \$last_name</p>\n";
print " <p>press continue to send to server</p>\n";
print " </card>\n";
print "</wml>\n";
}
这个程序会读取来自每个 card 元素所送出的参数,并且将他们以http get请求的型式传送给服务器。请注意在最后一个名为finish的card元素里面,我们在每一个 wml 变量(例如 $first_name)的前面全都加上一个斜线,这样才可以避免 perl 将它们误认为 perl 程序本身的变量来看待。一旦这些变量成功传送给服务器,我们的cgi程序便可以像其它任何一般的cgi变量那样读取它们。
2、编写控制客户端存取处理程序
wap设备是在低频宽的网络环境下运作的,因此它们首先将内容储存在自身的高速缓存里面,以避免无谓的资料请求与传送过程。只是传送cgi参数给我们的cgi程序并不能保证我们送出的内容不会被 wap 设备储存在高速缓存里面。无线上网设备会将它们储存起来,以 url 做为索引键值,接下来每当有指向到该 url 的请求的时候便会直接把之前储存的资料传回去,而不会向服务器询问这个页面从上次浏览过后是否已有更新过的资料。
在下面这个范例程序里面将时间与日期以wml的deck元素型式回传给wap设备,并且附有一个ok按钮以便再次向服务器要求传送新的当时时间与日期。这个程序也要求使用者输入他的名字,以便自定回传的内容。
#!/usr/bin/perl
use cgi;
use date::format;
print "content-type: text/vnd.wap.wml\n\n";
print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
print "<!doctype wml public \"-//wapforum//dtd wml 1.1//en\"
\"http://www.wapforum.org/dtd/wml_1.1.xml\">\n";
my $input = new cgi;
my $time = time2str("%a %b %e %t %y\n", time);
print "<wml>\n";
print " <card id=\"time_and_date\">\n";
print " <do type=\"accept\" label=\"ok\">\n";
print " <go method=\"get\" href=\"?\">\n";
print " <postfield name=\"name\" value=\"\$name\"/>\n";
print " </go>\n";
print " </do>\n";
if ($input->param("name")) {
print " <p>".$input->param("name").", </p>\n";
}
print " <p>现在时间是︰ ".$time."</p>\n";
print " <p>请输入你的姓名︰\n";
print " <input name=\"name\" emptyok=\"false\"/></p>\n";
print " </card>\n";
print "</wml>\n";
当我们把上面这个程序放入模拟器去执行,我们在模拟器的请求纪录文件里面发现下面这些纪录:
cache miss: http://wap.server.com/wml4.cgi
cache miss: http://wap.server.com/wml4.cgi?name=james
cache hit: http://wap.server.com/wml4.cgi?name=james
cache hit: <http://wap.server.com/wml4.cgi?name=james>
[1] [2] 下一页
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器