WML语言的基本情况
用于WAP的标记语言就是WML(Wireless Markup Language)。 WML的语法跟XML一样,WML是XML的子集。 HTML、XML和WML的文件有很多相似之处,这样网页开发者在过去10年中所学的东西今天依然适用。 WML页面文件的后缀是 *.WML,就象HTML的 *.HTML后缀。 XML规定定义了一个规范的XML文件的规格。任何违反这个规定的WML文件会出错。WML文件通常使用XML解释器起来解释。 建立网页制作环境 WML文件结构 文档的实体包含在<wml>...</wml>标记中,文档里每个CARD又包含在<card>...</card>标记中,然后实际的文字段落则包含在<p>...</p>标记中。 简单例子:
显示结果如下:
DECK里面各个组成部分的具体解释在本教程的其他部分有说明。 WML字符集
然而令人丧气的是,这种方法有些手机和模拟器并不支持(将来会的),所以目前第2种方法更普遍:不改变字符集设置,但是在写中文的时候采用UNICODE代表中文字符,如:
代表:
WML元素:标记(Tag)和属性 WML的主要内容是文本,由于标记会降低与手持设备的通讯速度,所以WML标准里仅仅使用了很少一部分。用于表格和图像的的标记几乎都被排除了。 与XML一样,在WML语言中,所有元素都放在符号"<" 和 ">"中,并且包含一个开始标志、一个结束标志和一个内容标志,或者使用自身结束的控制标记。就象这样:
WML同样支持在标志中标出属性。属性是标志的附加信息,与元素的内容不一样,它并不在屏幕上显示出来。属性通常在元素的开始标志后指定。如上面最后一个例子。 由于WML是XML的一种应用,因此所有的WML标记和属性都是大小写敏感的(<wml>跟<WML>完全不同),而且所有的标记都必须正确地结束。WML要求属性的值必须放在双引号或单引号内。单引号可放在属性标志内或双引号内。字符亦可作为属性的值。 WML注释
这些注释在浏览器中并不显示出来。 WML不支持嵌套元素注释。 链接(URL)
内部引用,如果next是当前DECK中的一个CARD时,可以用这种方式:
提供链接功能的WML元素有2个:<go>(参见任务)和<anchor>(参见事件)。 CDATA
浏览器窗口将显示如下内容:
| |||||||||||
有了上面的基础,相信大家已经能够做不少事情了。现在我们来深入一下,看看如何提高性能和网络传输效率。首先,需要介绍一下http 1.1(RFC2616)的基础知识。当然,如果你已经很熟悉了,可以跳过第一部分。 一、HTTP 1.1的简要介绍 所有的请求和响应都采用[RFC822]中定义的标准互联网消息格式,框架如下: 1、请求 2、响应 继续上面那个例子,如果该URL合法的话,服务器的响应会是这样的: <?xml version=”1.0”> …… 这个响应信息里包括了响应的数字代码和文本描述,然后是一组消息头。在一个换行符以后就是消息本体,在这里,消息本体就是www.itsalon.net/index.wml的源代码。 当用户终端接收到响应以后,会对其状态信息和消息头进行解码,然后决定对响应做出什么样的动作。如果收到OK响应,一般会把消息本体里的内容显示在屏幕上。对于桌面终端,通常是HTML,对于WAP浏览器,则是WML。 HTTP是一种很烦琐的协议。即使是简单没有任何数据的请求和响应都要产生数百字节的消息。WAP通过WAP网关来解决这个问题。WAP网关一个很重要的功能就是把所有的HTTP1.1消息转换成无线任务协议(Wireless Session Protocol, WSP)的消息格式。这种格式是压缩的二进制协议,兼容HTTP1.1。它能解析所有的请求和响应消息,并转换成最精简的BIT序列。 到这里我们已经介绍了HTTP1.1的主要内容。当然HTTP1.1还有很多复杂的内容,但是在这里并不打算多讲,如果你有兴趣,可以去相关网站查找它的资料。作者只想大家知道一点:用户终端和服务器之间还有比GET和POST请求更多的互动消息,它们一样有请求和响应消息头,并且可以包含一些信号来影响WAP应用程序的执行和性能。这正是提高WAP运行效率的秘密所在。 二、缓存(Caching) 由于WAP信道带宽的限制,我们在编写WAP应用的时候都希望最大限度地减少消息的传送量。要做到这一点,就要尽量地使用缓存,经常地从缓存中获得以前的消息。幸运的是目前大多数WAP设备都有一定级别的缓存,在默认情况下,会尝试最大化的缓存。几乎所有指向URL的响应都会被缓存下来。 当WAP用户终端缓存一个响应的时候,会保存几乎所有的信息:URL、响应文本、消息头以及其他可以验证响应的内容(参看下一节"验证和历史堆栈")。每个被缓存的项目都可以根据它的URL组成部分(域名、路径、协议、参数、端口等等)唯一的识别。 有两种HTTP消息头可以让你控制WML的DECK缓存,对我们最重要的是Cache-Control消息头。它能够直接通过请求/响应链来控制所有的缓存实体。所有的缓存机制都必须遵守这些消息头的定义。Cach-Control消息头通常用来屏蔽一个设备的默认缓存行为。他们在消息链中传递时必须直接穿过所有的代理服务器和网关而不被改变。 * Cache-Control: no-cache。设定这个选项的URL不能被缓存,包括用户终端和所有处于内容服务器和用户终端之间的其他服务器; 在写一个WAP应用的时候,你要先假设用户终端会尽量最大化缓存以便使向内容服务器获取信息的动作减少到最少。下面做些解释: 1、永久缓存URL * 指定一个离现在很远的过期日,比如:Expires: Tue, 01 Jan 2002 00:00:00 GMT; 2、指定对URL的缓存时间 另外一种控制缓存时间的方法是使用前面提到过的Expires,不过这种方法只能告诉用户终端:只要过了指定时间,无论什么时候访问页面都要刷新。如果你下次要控制时间,只能改变Expires里的时间值。 3、禁止对URL的缓存 实际上,后两种不是最好的选择。首先这样会多占用终端的处理时间,因为当碰到这个DECK时,终端需要计算一下过期时间。其次,这样会多占用一些字节,而且在表达上也不够清楚。 三、验证(validation)和历史堆栈(History Stack) WAP标准规定所有的WAP设备都至少要有可以容纳10-个项目的历史堆栈。当用户按下由<go>或其他转向指令的定义的前行(forward)链接时,URL被推(push)入堆栈。如果按下由<prev>定义的后退(backward)链接,URL被弹(pop)出。 一般情况下,所有的前行链接都会被验证,而后退链接则不会,因为它已经在cache里了。可是我们有时候还是希望当用户按下后退键时依然能够得到最新的数据。如果终端总是不予验证的话,那用户只好找到主菜单再重新进入那个页面。 幸运的是,我们用Cache-Control:must-revalidate就可以强迫用户终端在用户按back时对URL进行验证。当然,进行验证并不是说该页面会立刻重新读取,而是根据他是否过期来决定。如果没有过期,验证的结果仍然是显示缓存中的页面。 如果你需要每次back都重新读取页面,用Cache-Control:must-revalidate, no-cache可以实现。另外,把 no-cache换成max-age=300就可以在back时对已缓存了300秒的页面进行刷新。 四、HTTP头与meta元素 <meta http-equive="Expires" content=" Mon, 10 Jan 2000 00:00:00 GMT"/> 当网关在WML文档中扫描到元素时,就会把它们转换成WSP等效的HTTP消息头,然后用户终端就可以据此对缓存进行控制了。 |