1. 开发WAP软件需要哪些工具?
为了开发WAP应用程序,需要一个WAP网关(注意:这里的网关可能是指支持WML的服务器。可以通过配置WWW服务器达到这个目的)和WAP工具包。工具包应当包括模拟器和能让开发者浏览WML网页。WML页面的开发和HTML页面的开发一样,可以使用Notepad或者其他文本编辑器来进行编辑。
2. 有哪些公司现在提供这样的开发环境?
Nokia、Ericsson、UpPhone和Motorola都提供免费的WAP网关和工具包。 Nokia:Nokia Toolkit和Nokia WAP Server。 Ericsson:Ericsson R320和WapIDE。 UpPhone:UpPhone SDK。 Motorola:Motorola ADK。
3. 开发WAP应用一定要有WAP手机吗?
不是,当开发WAP应用的时候,不一定需要WAP手机。模拟器可以帮助开发者解决大部分的问题。但是如果是开发商业网站,特别是想知道各种移动电话在显示WML页面上的差别的时候,最好是配备一个。目前各种手机对WML标记的支持和中文的支持状况大不相同,因此WAP手机还是必要的。
4. 开发者需要一个WAP网关吗?
不是很必要。如果只想进行简单的WAP内容服务,可以使用现有的Web服务器(只需要修改MIME类型)。移动电话会通过坐落在本地的网关连接到你的服务器上。 但是在网关上驻留开发者的程序有很多好处。既然开发者的程序是网关的一个部分,开发者就可以知道呼叫号码、身份、位置等等。
5. 可以看到WML的源代码么?
如果开发者使用SDK浏览的时候将能够看到WML的代码。如果只有一个HTML浏览器,可以访问“Fetch Page”服务(http://www.webcab.de)来取得代码。这个可以显示在Internet上的任何WML页面中。
6. 可能在WML中加入applets吗?
不能。
7. 可以使用HTML开发工具来开发WAP应用吗?
在大多数情况下开发工具是使用基于PC的浏览器。HTML、javascript和Java对于WAP开发来说都没有用处。但是,越来越多的开发工具在加入对WML的支持。 Allair的Cold Fusion 4.5 和 HomeSite已经有WML支持,虽然Allair也许需要清除一些BUG。另外PHP和ASP在Coldfusion/HomeSite也能支持。 可以到 Marjolei Katsma的 HomeSite Help site 上得到更多的信息。
8. 可以通过WML页面来操作数据库吗?
可以,与创建HTML页面相同。任何相关的服务器端的技术都可以用来生成WML页面。
9. 可以使用CGI生成WML页面吗?
当然。可以用创建HTML同样的方法来创建WML。如果想书写一个CGI来创建WML,只要记住在页面的开头正确设置MIME类型。具体的形式根据所使用的语言不同而不同。例如在Perl中:
print (“Content-type:application/vnd.wap.wml /n/n/n”);
注意至少要使用2个换行。
10. 如何使用Cold Fusion来生成页面?
使用Cold Fusion只需要加上:
<CFCONTENT type=”text/vnd.wap.wml”>
11. 如何使用PHP来书写动态的WML页面?
PHP(和大多数其他服务端脚本语言一样)可以被用来书写动态的WML内容。只需要将输出的标记限制在WML微型浏览器可接受的范围内。 注意PHP有很多内建的HTML功能,特别是错误功能,这些功能WML微型浏览器可能无法识别。 PHP同样可以在一个HTML文件中编写出既适合于HTML,也适合于WML的内容。PHP的源代码对于客户端来说是不可见的。因此可以针对HTML浏览器输出HTML页面,针对WML浏览器输出WML页面。 可以在开发PHP编写的WML页面的时候把以下代码加在开头:
<?
// header(“Content-type: text/vnd.wap.wml”); echo(“<?xml version=/”1.0/”?>/n”); echo(“<!DOCTYPE wml PUBLIC /”-//WAPFORUM//DTD WML 1.1//EN/” //”http://www.wapforum.org/DTD/wml_1.1.xml/”>/n/n”); ?>
基于PC的浏览器将忽略这些无法理解的WML标记。但是如果想在WAP设备或者模拟器上测试的时候,只需要将”//”去掉,页面自动变成WML页面。
12. 使用PHP动态输出WML
这些例子生成一个非常有用的应用叫做:PizzaCalc。它将输入所有的pizza的帐单和人的数目,可以算出每个人的花费。 应用生成一个动态的页面叫做“calc”或者“input”。注意到所有的转义字符例如双引号。该页显示了一个简单的变量处理,和如何传递参数到另外的卡片: 使用WML浏览器就可以测试应用程序: http://wap.colorline.no/wap-faq/apps/pizzacalc.html。 或者输入: http://wap.colorline.no/demos.html选择应用。
<? header(“Content-type: text/vnd.wap.wml”); echo(“<?xml version=/”1.0/”?>/n”); echo(“<!DOCTYPE wml PUBLIC /”-//WAPFORUM//DTD WML 1.1//EN/” /”http://www.wapforum.org/DTD/wml_1.1.xml/”>/n/n”); echo(“<!–The application PizzaCalc was originally made by The Crusaders www.crusaders.no on the Commodore Amiga –>/n”); echo(“<!– It was unfortunately not possible to emulate the crap interger handling of the original program –>/n”); ?>
<wml> <? if($action == “calc”) { echo(“<card id=/”result/” title=/”PizzaCalc/”>/n”); echo(“<do type=/”prev/” label=/”Back/”>/n”); echo(“<go href=/”pizzacalc.html#input/”/>/n”); echo(“</do>/n”); echo(“<p>/n”); echo(“The cost per eater will be “.$total / $eaters.”<br/>/n”); } else { echo(“<card id=/”input/” title=/”PizzaCalc/”>/n”); echo(“<p>/n”); echo(“<anchor>Split Pizza bill <go href=/”pizzacalc.html?total=/$(total)&eaters=/$(eaters)&action=calc/”/> </anchor>/n”); echo(“<br/>/n”); echo(“Total cost: <input type=/”text/” name=/”total/” format=/”*N/”/>/n”); echo(“Eaters: <input type=/”text/” name=/”eaters/” format=/”*N/”/>/n”); } ?> </p> </card> </wml>
13. 可以使用Java Servlet来生成WML页面吗?
当然。可以使用创建HTML同样的方法来创建WML。如果想书写一个CGI来创建WML,只要记住在页面的开头正确设置MIME类型: response.setContentType(“text/vnd.wap.wml”);
14. 可以使用ASP、Perl等生成动态的应用吗?
是的。可以使用任何服务器端的脚本语言来生成WAP应用。
15. 如何使用ASP书写WML内容?
ASP(Active Server Pages)可以做到和PHP一样,也可以用来书写动态的WML。如果需要一些好的例子请参考Luca Passani’s WAP and ASP articles。或者查看Jean-Luc Praz’s (jeanluc@corobori.com)。更多的ASP例子在:http://www.corobori.com/wap/。
16. 在使用ASP动态输出WML页面的时候,已经设置了Content-type,但是浏览器返回的仍然是text/html,有什么问题吗?
如果在ASP脚本中有一个错误,那么诊断程序会发还一个HTML页面,请检查脚本。
17. 在使用ASP生成WML页面的时候出现了错误: <MIME type “text/html” is not supported>,会是什么问题?
这个问题是Web浏览器不知道WML的正确类型,修改ASP的第一行,加入:
<Response.ContentType = “text/vnd.wap.wml”>
后就可以工作了。
18. 下面的代码有什么问题吗?
<%Response.ContentType = “text/vnd.WAP.WML”%> <?xml version=”1.0″?>
去掉<?xml version=”1.0″?>之前的空格。XML解释器希望在这行中没有其他字符,甚至是空行。
19. ASP代码可以在模拟器上工作,在真正的浏览器上怎么不行?
在很多模拟器上没有像真正的WML浏览器那么严格。这些对于那些没有使用网关的模拟器(Nokia SDK/Toolkit)来说更是这样,有些就根本没有使用网关(WinWAP、WapMAN)。 一个真正的WML浏览器应该只读取二进制的数据(从WML编码得来的)WMLC,对于网关应该将文本WML转换/编译成WMLC。语法是非常严格的。ASP是为HTML浏览器设置的,但是HTML没有WML那么严格。 这里在ASP生成动态页面的时候有一个微小的“bug”。它在WML浏览器上不允许有任何地方输出白行(例如:空格,回车,换行)。注意到有些网关可能会修正这些问题,但有的则不管(例如:CMG网关)。 下面是一个常见的ASP代码用来输出WML页面开头的MIME类型:
<%Response.ContentType = “text/vnd.wap.wml”%> <?xml version=”1.0″?>
问题就在ASP将会在 .wml”%> 和 <?xml vers 之间输出换行和回车。这两行就被分割了。这将打乱WML代码的内容。WML必须以“<”开头,而且第一行是<?xml version=”1.0″?>。就上面的WML页面回车/换行将会出现问题。 最简单的解决办法是:
<%Response.ContentType = “text/vnd.wap.wml”%><?xml version=”1.0”?>
在XML定义正确的格式化以后,后面的部分WML对空格就没有那么严格的要求。
要注意的是有些网关在输出ASP的时候会有问题,因此在WML代码中最好使用 Response.Write 而不是<%=MyVar%>。
20. 如何使用Perl来生成WML内容?
和其他Server端程序一样。Perl也可以用来书写漂亮的WAP应用程序。 最常见的就是如何使用Perl输出正确的MIME类型,下面的例子说明了这一点:
print “Content-type: text/vnd.wap.wml/n/n”; print “<?xml version=/”1.0/”?>/n”; print “<!DOCTYPE wml PUBLIC /”-//WAPFORUM//DTD WML 1.1//EN/” /”http://www.wapforum.org/DTD/wml_1.1.xml/”>/n”; print “<wml>/n”; ……
21. 应当如何下手书写WAP应用程序?
其实需要的只是Text编辑器。但是使用一个开发工具可以节约很多时间。 在这之前应该浏览一下WAP的权威站点:www.wapforum.com。 在Nokia WAP 开发论坛中进行注册,并且下载Nokia WAP Developer Toolkit 。Toolkit中的PDF文件可以给出一定的WML和WMLScript指导。Nokia Toolkit需要JRE (Java Runtime Environment) v.1.2.2 或者更高版本。 虽然工具可以用来为WAP设备设计应用,但是不是为专门的移动电话。在WAP开发工具上所看到的并不代表用户在手机上所看到的。为了确定想看到的事情,最好需要一个WAP设备,例如移动电话,或者模拟器。 Nokia WAP SDK 2有一个7110的模拟器。模拟器是一个有效的检测方式,能检测程序中的bug。 Nokia SDK 同样还包括一个小的WAP server让开发者可以从本地或者HTTP服务器上下载WML页面。 到 Phone.com 开发站点注册后,Phone.com 提供UP.browser。这是最流行的浏览器,特别是在美国,Phone.com 提供UP.SDK。 在注册之后就可以下载。 对于Ericsson R320 和 R380是最近的事情。应该注册并查看Ericsson’s Developer’s Zone 来得到开发工具。R380是一个非常好的模拟器,在 Symbian 不需要注册就可以下载。Ericsson 没有公开的为R320的模拟器。 Motorola 有一个平台叫做 Mobile Internet eXchange 或者 MIX 。Mobile Application Development Kit 已经开发出一个开发平台,即为WAP也为Motorola的 VoxML。在注册后,可以在下面的网址找到数据包。
http://www.motorola.com/MIMS/MSPG/cgi-bin/spn_madk.cgi.
WAPmine 是一个独立的应用,叫做 WAPPage 是一个所见即所得的编辑工具。而且有一个XML树型控件来编辑WML标签。 如果在开发公共应用程序时,想在很多设备上测试你的程序,就像在不同的浏览器上测试HTML页面一样。注意在不同的WML浏览器上的差别,可能比在不同的HTML浏览器上的差别要大。
22. 如何编写和测试WML页面?
现在有很多SDK。AnywhereYouGo.com有WAP SDK和IDE列表,可以下载一个来用。任何文本编辑器都可以书写一个简单的WML页面,当然HTML编辑器也可以(特别是那些支持个人定义标签的),例如:Allaire Homesite (http://www.allaire.com )。可以使用SDK来做简单的测试,但是对于大的项目可能要困难些。AnywhereYouGo.com已经建立一套基于Web的工具来帮助WAP测试。
23. 哪儿可以在找到WML的测试工具?
首先确定WML代码是正确的,然后再使用WML测试工具。 有一个非常好的测试工具在Zygo Communications(http://wap.z-y-g-o.com/tools/),测试工具是用Perl写的。里面还有其他的工具可供下载。
24. 如何操作WML页面?
操作WML页面或者卡片,最简单的办法是通过现有的网关。大多数移动电话提供者将功能都放在主页上,在上面可以通过WAP设备操作。网关的链接一般叫做“Go to URL”。当选择以后,WAP设备将通过网关操作指定的普通IP或者URL。在这种情况下,网关读取从WAP设备发送给网关的WML内容,就像PC浏览器读取内容的过程一样。 有些营运商选择不让他们的用户操作其他的站点。这个就像Internet Service Provider只允许用户操作ISP自己的站点。像这样的做法是不明智的,这样会发现自己的用户去其他地方了。 如果要坚持这种方法,可以通过ISP拨号或者使用一个公共的网关来取得其他的WAP资源。
25. 有没有一个友好的方式来管理WML内容?
还没有。虽然Oracale正在开发数据库驱动的文档服务,被称为Panama,可以支持WAP分发。
26. 如何防止用户代理cache页面?
如果用户使用ASP,应该加入一行<%Response.expires=-1%> ,这个将阻止Cache。
27. 怎样防止从Cache中读取WML页面?
当WML页面下载到WAP设备后,它将保存在WAP设备内存中一段时间,直到这个时间过期。在这之后,页面将从服务器下载,而不是从WAP设备的缓存读取。这个过程被称做Cache。 但是有些时候不想让页面从缓存中读取,而是从服务器端读取。一个典型的例子就是当服务器的内容不断在更新的时候,通过在HTTP头中加入一定的cache信息,来告诉WAP设备该页面将不存储在缓存中。 可以在服务器端生成HTTP头,或者使用PHP、ASP、Perl或者其他服务端开发语言。这一行不能被包括在页面里,既然是HTTP的信息头,就不是WML元素。 对于静态页面,或许没有使用服务器端脚本语言,许多浏览器支持META标签来控制浏览器的Cache。看本部分的最后的例子。 将下面代码加入到HTTP头中,页面将马上过期:
Expires: Mon, 26 Jul 1997 05:00:00 GMT Last-Modified: DD. month YYYY HH:MM:SS GMT Cache-Control: no-cache, must-revalidate Pragma: no-cache
第一行告诉微型浏览器,页面已经过期一段时间了。第二行告诉浏览器页面最后一次修改的时间。DD应该换成当天的日期,month YY HH MM SS等等类推。第三行和第四行有同样的效果。告诉浏览器页面不被Cache(第三行适用于 HTTP 1.1,第四行适用于HTTP 1.0)。 下面的是PHP的一个例子:
<? // set the correct MIME type header(“Content-type: text/vnd.wap.wml”); // expires in the past header(“Expires: Mon, 26 Jul 1997 05:00:00 GMT”); // Last modified, right now header(“Last-Modified: ” . gmdate(“D, d M Y H:i:s”) . ” GMT”); // Prevent caching, HTTP/1.1 header(“Cache-Control: no-cache, must-revalidate”); // Prevent caching, HTTP/1.0 header(“Pragma: no-cache”); ?>
下面是使用WebClasses(VB)的例子。使用”Response.Expires=-1″,防止Cache。
Private Sub WebClass_Start() ‘Set correct MIME type Response.ContentType = “text/vnd.wap.wml”
‘Make sure no caching Response.Expires = -1 Response.AddHeader “Pragma”, “no-cache” Response.AddHeader “Cache-Control”, “no-cache, must-revalidate”
‘Use basicwml(my own) as template Set NextItem = basicwml End Sub
这里有一个ASP的例子,同样使用“Response.Expires=-1”防止Cache。
<% Response.ContentType = “text/vnd.wap.wml” Response.Expires = -1 Response.AddHeader “Pragma”, “no-cache” Response.AddHeader “Cache-Control”, “no-cache, must-revalidate” %>
最后是使用META的例子:
<?xml version=”1.0″?> <!DOCTYPE wml PUBLIC “-//WAPFORUM//DTD WML 1.1//EN” “http://www.wapforum.org/DTD/wml_1.1.xml”> <wml> <head> <meta forua=”true” http-equiv=”Cache-Control” content=”max-age=0″/> </head> <card id=”alwaysexpire”> <p>This deck will never be stored in the cache</p> </card> </wml>
下面的页面是在经过86400秒(24 hours)后过期。
<?xml version=”1.0″?> <!DOCTYPE wml PUBLIC “-//WAPFORUM//DTD WML 1.1//EN” “http://www.wapforum.org/DTD/wml_1.1.xml”> <wml> <head> <meta forua=”true” http-equiv=”Cache-Control” content=”max-age=86400″/> </head> <card id=”expire1day”> <p>This card will live in the cache for a day</p> </card> </wml>
有些浏览器例如:UP.Simulator如果可以通过“返回”达到另外一个卡片,那么它将不会重新装载卡片。为了强制这个更新动作,用户必须在META标签中使用must-revalidate 参数。
<meta forua=”true” http-equiv=”Cache-Control” content=”must-revalidate”/>
28. 如何防止变量被保存在Cache中?
变量保存在Cache中,这样变量还可以再利用。例如当用户返回到上一个输入卡片,他不需要重新输入,只需要改变需要改变的地方。但是在某些情况下这会造成一些问题。例如以WAP聊天系统,有些变量用了一遍又一遍,但是需要不同的内容。有些浏览器,例如:Nokia 7110,就会存在类似的在该清除的时候无法清除的问题。 在WML中,<card>标签有一个参数叫做newcontext。 当newcontext=”true” 时清除所有的变量。但是这样也清除了所有导航的历史记录,这意味着back按钮不再工作。 为了清除变量,可以告诉浏览器将变量设为空:
<setvar name=”one_variable” value=””/> <setvar name=”another_variable” value=””/>
但是,不是每个时候都有效果。在某些情况下必须使用一个难以想象的方法来清空变量。就是使用 onenterforward 事件。
<onevent type=”onenterforward”> <refresh> <setvar name=”one_variable” value=””/> <setvar name=”another_variable” value=””/> </refresh> </onevent>
29. 怎么能够知道请求是从WML浏览器来的还是HTML浏览器来的?
既然要利用已经存在的为HTML浏览器编写的代码,就需要知道请求是从HTML浏览器还是从WML浏览器过来的。同样地,如果想重新引导的HTML浏览器直接到相应的HTML文档上,WML浏览器到WML页面上,以下的PHP代码就可以做到这些。
<? // Because this script sends out HTTP header information, // the first characters in the file must be the <? PHP tag.
// relative URL to your HTML file $htmlredirect = “/html/my_htmlpage.html”; // ABSOLUTE URL to your WML file $wmlredirect = “http://wap.mysite.com/wml/my_wmldeck.wml”;
if(strpos(strtoupper($HTTP_ACCEPT),”VND.WAP.WML”) > 0) {// Check whether the browser/gateway says it accepts WML. $br = “WML”; } else { $browser=substr(trim($HTTP_USER_AGENT),0,4); if($browser==”Noki” || // Nokia phones and emulators $browser==”Eric” || // Ericsson WAP phones and emulators $browser==”WapI” || // Ericsson WapIDE 2.0 $browser==”MC21″ || // Ericsson MC218 $browser==”AUR ” || // Ericsson R320 $browser==”R380″ || // Ericsson R380 $browser==”UP.B” || // UP.Browser $browser==”WinW” || // WinWAP browser $browser==”UPG1″ || // UP.SDK 4.0 $browser==”upsi” || // another kind of UP.Browser ?? $browser==”QWAP” || // unknown QWAPPER browser $browser==”Jigs” || // unknown JigSaw browser $browser==”Java” || // unknown Java based browser $browser==”Alca” || // unknown Alcatel-BE3 browser (UP based?) $browser==”MITS” || // unknown Mitsubishi browser $browser==”MOT-” || // unknown browser (UP based?) $browser==”My S” || // unknown Ericsson devkit browser ? $browser==”WAPJ” || // Virtual WAPJAG www.wapjag.de $browser==”fetc” || // fetchpage.cgi Perl script from www.wapcab.de $browser==”ALAV” || // yet another unknown UP based browser ? $browser==”Wapa”) // another unknown browser (Web based “Wapalyzer”?) { $br = “WML”; } else { $br = “HTML”; } }
if($br == “WML”) { // Force the browser to load the WML file instead header(“302 Moved Temporarily”); header(“Location: “.$wmlredirect); exit; } else { // Force the browser to load the HTML file instead header(“302 Moved Temporarily”); header(“Location: “.$htmlredirect); exit; } ?>
这个判断是在服务端完成的, PHP代码将首先查看网关是否接收text/vnd.wap.vml MIME类型。如果不是,将检测前面的字符,查看是否为WML浏览器。如果不符合,那么就假设为HTML浏览器。如果有新的WML浏览器,那么ID字符串也要增加。 这个代码基于Robert Whitinger(robert@wapsight.com)的代码,使用了Don Amaro(donamaro.concepcion@nl.unisys.com)提供的列表。 注意:由于只需要四个字符串就可以辨别,因此例如:”WapIDE-SDK/2.0;(R320s(Arial))” 可以使用“WapI”来代替是可行的做法,也是足够的。 同样的功能也可以通过ASP来解决。先判断请求的是“/index.wml” 或者 “/index.html” 和所需要的MIME类型。另外以下的脚本辨别的方式和上面不一样。另外还需要网关告诉服务器它能接收 的text/vnd.wap.wml MIME类型。该例子如下所示:
<% Response.Buffer = TRUE Dim IsWap httpAccept = LCase(Request.ServerVariables(“HTTP_ACCEPT”)) if Instr(httpAccept,”wap”) then IsWap=1 Else Response.Redirect “/index.html” : Response.Flush : Response.End End if %> <%Response.ContentType = “text/vnd.wap.wml”%><?xml version=”1.0”?> <%Response.Flush%> <!DOCTYPE wml PUBLIC “-//WAPFORUM//DTD WML 1.1//EN” “http://www.wapforum.org/DTD/wml_1.1.xml”> <wml> <card id=”redirect”> <onevent type=”onenterforward”> <go href=”/index.wml”/> </onevent> <p> <a href=”/index.wml”>enter</a> </p> </card> </wml> <%Response.Flush:Response.End%>
|