<p> 随着手机用户的不断增加,WAP站点如雨后春笋迅速的滋长开来,手机邮箱也不断的出现在人的眼前,笔者也曾经开发了一套手机邮箱的系统,但由于时间仓促再加上后来一直忙于工作事情,系统功能也就再未加强,今日有幸借助于IT168原创网公开出来,与大家共同分享,希望大家可以借题发挥,加强系统功能,能够更好的应用于实际。</p><p> 测试软件:Opera M3gate</p><p> 测试机型:Eg730+ Nokia 6681 Moto V3i</p><p> 邮件组件:W3 Jmail 4.4</p><p> 一、WML结构介绍</p><p> 首先我们先对WML的结构作个简单的介绍,以便于大家更好的浏览源码。</p><code> 〈?xml version="1.0"?〉<br /> 〈!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1xml"〉<br /> 〈wml〉<br /> 〈head〉<br /> 〈access/〉<br /> 〈meta..../〉<br /> 〈/head〉<br /> 〈card〉<br /> Some contents...<br /> 〈/card〉<br /> 〈wml〉</code><p> 我们根据以上结构举个最简单的例子:</p><code> 〈% @LANGUAGE="VBSCRIPT" CODEPAGE="65001" %〉<br /> 〈%Response.ContentType = "text/vnd.wap.wml; charset=UTF-8"%〉<br /> 〈?xml version="1.0"?〉<br /> 〈!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1xml"〉<br /> 〈wml〉<br /> 〈card title="邮件系统"〉<br /> 〈p〉<br /> WML开发邮件系统<br /> 〈/p〉<br /> 〈/card〉<br /> 〈/wml〉</code><p> 将以上代码存为example.asp,直接通过M3gate查看,具体效如图一。</p>
<p> </p>
<p> <img src="/content/uploadfile/200805/2008053117025806.jpg" onclick="get_larger(this)" title="请点击图片查看原图" /></p><p> 图一</p><p> “邮件系统”这一段文字为UTF-8码,为了更好的适用于手机浏览,建议编码格式采用UTF-8,大家可以下载WAP编码转换器对中文进行转换。</p><p> 由于我们系统采用ASP语言开发,因此在以上代码段前面还需加上以下两段代码:</p><p> 〈% @LANGUAGE="VBSCRIPT" CODEPAGE="65001" %〉</p><p> 指定IIS以UTF-8的编码格式读取传递过来的串串(表单提交,地址栏传递等),如果需要以GB2312的格式读取,可以将65001换成936。</p><p> 〈%Response.ContentType = "text/vnd.wap.wml; charset=UTF-8"%〉</p><p> 指定页面输出格式为WML,并且编码为UTF-8</p><p> 二、JMail组件功能介绍</p><p> W3 Jmail是一个smtp组件,利用它可以发送邮件,支持html格式邮件。你可以访问主页:http://tech.dimac.net 下载这个组件。w3 Jmail 发送邮件速度快,功能丰富,并且是免费的。</p><p> 以下是本系统所要用到的相关函数及属性,如需更详细的资料可以查阅JMail的官方说明。</p><p> 1、JMAIL.POP3</p><p> 创建POP3对象</p><p> Set pop3 = Server.CreateObject( "JMail.POP3" )</p><p> Connect(Username, Password, Server, Port) :</p><p> 打开并连接POP3服务器,</p><p> Username:邮箱用户名</p><p> Password:邮箱密码</p><p> Server:POP3服务器</p><p> Port:服务器端口号,可选项,默认为110</p><p> 示例:mailbox.Connect "john", "qwerty", "mail.myDomain.com"</p><p> Disconnect() :</p><p> 关闭连结</p><p> 示例:mailbox.Disconnect</p>
<p> </p>
<p> DeleteSingleMessage(MessageID) :</p><p> 从邮件服务器上删除由MessageID指定的邮件。</p><p> Mailbox.DeleteSingleMessage 1</p><p> Messages() : Pointer</p><p> 返回Message的集合</p><p> set messages = mailbox.Messages</p><p> 2、JMAIL.MESSAGE</p><p> 建立Message对象:</p><p> set Message=server.CreateObject("Jmail.message")</p><p> Silent() : Boolean</p><p> 如果设置为true,JMail不会抛出例外错误. JMail.execute() 会根据操作结果返回true或false</p><p> 示例:Message.silent = true</p><p> Charset() : String</p><p> 字符集,缺省为"US-ASCII"</p><p> 示例:Message.Charset = "US-ASCII"</p><p> From() : String</p><p> 发件人</p><p> 示例:Message.From=”sn1985boy@sohu.com”</p><p> Subject() : String</p><p> 发送主题</p><p> 示例:Message.Subject=”测试”</p><p> Body() : String</p><p> 邮件主体部分</p><p> 示例:Message.Body=“恭喜发送成功!”</p><p> MailServerUserName() : String</p><p> 用户名</p><p> 示例:Message.MailServerUserName=“*****”</p><p> MailServerPassWord() : String</p><p> 密码</p><p> 示例:Message.MailServerPassWord=”********”</p><p> MailDomain() : String</p><p> 邮件服务器的域名</p><p> 示例:Message.MailDomain=”www.sohu.com”</p><p> Priority() : Byte</p><p> 紧急程度,默认为3,1为最快,5为最慢</p><p> 示例:Message.Priority=2</p><p> Send(mailServer, enque) : Boolean</p><p> 发送邮件。邮件服务器是一个描述邮件服务器名称或地址的字符串,用户名和密码是可选项。当要发送认证邮件时使用格式为:用户名:密码@邮件服务器</p>
<p> </p>
<p> 示例:</p><p> Message.Send("myMailServer"), Message.Send("myUserName:mypassword@mymailserver.mydomain.com")</p><p> Count() : Integer</p><p> 返回邮件数</p><p> 示例:i = mailbox.Count</p><p> Item(Index) : Pointer</p><p> 返回一个Message对象</p><p> 示例:set msg = Messages.Item(0)</p><p> Recipients() : Pointer</p><p> 返回收件人集合。</p><p> 示例:Set Recipients = msg.Recipients</p><p> Attachments() : Pointer</p><p> 返回邮件的附件集合。</p><p> 示例:Set Attachments = msg.Attachments</p><p> 3、JMail.Recipients</p><p> Count() : Integer</p><p> 返回集合中收件人的总数。</p><p> 示例:i = Recipients.Count</p><p> Item(Index) : Pointer</p><p> 返回集合中的一个指定的收件人。</p><p> 示例:set re = Recipients.Item(0)</p><p> 4、JMail.Attachments</p><p> Count():Integer</p><p> 返回集合中附件的总数。</p><p> 示例:i = Attachments.Count</p><p> 三、邮件系统介绍</p><p> 本邮件系统共包括登陆邮件、发送邮件、接收邮件、删除邮件、回复邮件五个功能,以下我们就对每个功能进行单独介绍,并附出源码,本教程所有图片为M3gate测试中的截图。</p><p> 1) 登陆邮件</p><p> <img src="/content/uploadfile/200805/2008053117025813.jpg" onclick="get_larger(this)" title="请点击图片查看原图" /></p><p> 图二</p><p> 从图二中我们可以看出,登陆页面包括一个表单,表单中含有两个文本框与一个发送按钮,那么在WML语言中是如何提交表单的呢?首先我们先看看wml语言中一些表单元素:1、input元素</p><p> 〈input name="user" title="label" type="type" value="value" default="default" format="specifier" emptyok="false|true" size="n" maxlength="n" tabindex="n"/〉,用来输入文本,除了name属性是必要的,其他可选。</p>
<p> </p>
<p> *name属性:指定了用来存储该输入文本的变量名字。</p><p> *title属性:该输入框的名字,同样可被用来作为概要CARD页中的选项名。</p><p> *type属性:默认值为text,如选择password,则输入的数据显示为*。</p><p> *value属性:在语法和行为上等同于下面的default属性,</p><p> *default属性:指定输入框的默认值,即name属性指定变量的默认值,当用户输入新值时,该值无效,如果该值不符合以下format属性的规定,则手机也忽略该默认值。</p><p> *format 属性:用来格式化输入的数据,可用的标记如下,使用时可用“一位数字标记”和“*标记”的形式,前者代表N个标记型字符,如3X, 后者代表任意个(小于maxlength属性的值)标记型字符。</p><p> 标记 描述</p><p> A 任何符号或者大写字母(不包括数字)</p><p> a 任何符号或者小写字母(不包括数字)</p><p> N 任何数字(不包括符号或者字母)</p><p> X 任何符号、数字或者大写字母(不可改变为小写字母)</p><p> x 任何符号、数字或者小写字母(不可改变为大写字母)</p><p> M 任何符号、数字或者大写字母(可改变为小写字母)或者多个字符,默认为首字大写</p><p> m 任何符号、数字或者小写字母(可改变为大写字母)或者多个字符,默认为首字小写</p><p> *maxlength属性:指定了用户可输入的最大字符长度,最大限制为256个字符。</p><p> *emptyok属性:表示用户可否不填输入框,默认为false,即要填。</p><p> *size属性:输入框显示长度,目前未被支持。</p><p> *tabindex属性:类似于在HTML表单中按TAB键后,焦点落在哪个选项上,该值决定了这个选择顺序,数字大的排在后面。目前未被支持。</p><p> 示例:</p>
<p> </p>
<p> 〈input type="text" title="用户名" name="user" maxlength="50"/〉</p><p> 2、do元素</p><p> Do是WML语言中最有有价值的元素之一,它给用户提供一种在当前Card上进行"动作"的通用方法。</p><p> 属性列表:</p><p> *type属性:告诉浏览器动作的意图。</p><p> WML总共声明了9个类型的动作,最常用的动作类型是"accept"和"option"。</p><p> 1、accept,接受、确认</p><p> 2、prev,返回上一个历史堆栈中的URL</p><p> 3、help,请求帮助</p><p> 4、reset,清除或者重置状态</p><p> 5、options,根据当前页面的功能设置选项。</p><p> 6、delete,删除选择条目</p><p> 7、unknow,相当于空白字串</p><p> 8、vnd.*。vnd.*及其它不同大小写组合[Vv][Nn][Dd].*。这种类型定义的都是vnd.cotype,用于激活供应商或用户浏览器自定义的某个特定功能,其中co为公司(company)名的缩写。</p><p> 9、X-*与X-*。扩展类型,目前WML中还没有使用。</p><p> *label属性:设置按钮标题,显示在浏览器定义好的屏幕位置,不同浏览器地显示位置不同。如果不设置标题,按钮会按照浏览器的缺省格式显示,不同浏览器的缺省格式不同。</p><p> * name属性:按钮名称,可以用Card级的动作覆盖template上的同名动作,重新赋予那些动作新的任务。</p><p> *optional属性:来定义一个按钮是否显示,设置为True时会被浏览器忽略</p><p> 示例:</p><code> 〈do type="accept" label="发送" optional="false"〉<br /> {Content}<br /> 〈/do〉</code><p> 3、go元素</p><p> 用来指示浏览器显示指定的URL,包括DECK的第一个CARD或者指定的CARD。语法如下:</p>
<p> </p>
<code> 〈go href="url" sendreferer="false|true" method="get|post" accept-charset="charset"〉<br /> 〈postfield name="name" value="value"/〉<br /> 〈setvar name="name" value="value"/〉<br /> 〈/go〉</code><p> 其中href属性为必选,其他为可选。</p><p> *sendreferer属性:是否传递当前页的URL,默认值为false。</p><p> *method属性:和HTML中的表单FORM的method属性一样,指定表单是以get的方式还是post的方式递交,默认的值为get,但如果未指定method但〈go〉〈/go〉间存在〈postfield〉,手机自动以post方式传递。</p><p> *accept-charset 属性:可覆盖在HTTP头里指定的字符集,可以写多个字符集,如accept-charset="UTF-8,US-ASCII, ISO-8859-1"。</p><p> 〈postfield name="name" value="value"/〉可以看作是HTML表单FORM中的〈INPUT TYPE="HIDDEN" NAME="变量名" VALUE="值"〉,通过它可以向指定的URL传递以“变量名/值”形式的数据。name和value属性都是必选的。注意只有这里的变量是用来递交给CGI程序的。</p><p> 除了〈postfield〉,还可以在〈go〉和〈/go〉间加入一句或者多句〈setvar name="name" value="value"/〉,该语句的意思是,当触发某一事件时,给变量赋值。</p><p> 示例:</p><code> 〈go href="main.asp" method="post" accept-charset="utf-8"〉<br /> 〈postfield name="user" value="$(user)"/〉<br /> 〈postfield name="pwd" value="$(pwd)"/〉〈/go〉<br /> 〈/do〉</code><p> 邮件登陆界面源码: Index.asp</p>
<p> </p>
<code> 〈% @LANGUAGE="VBSCRIPT" CODEPAGE="65001" %〉<br /> 〈%Response.ContentType = "text/vnd.wap.wml; charset=UTF-8"%〉<br /> 〈?xml version="1.0" encoding="utf-8"?〉<br /> 〈!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"〉<br /> 〈wml〉<br /> 〈card title="邮箱登陆"〉<br /> 〈p align="center"〉<br /> Welcome To Sohu-WAP-Mail〈/p〉<br /> 〈p〉<br /> 用户名:<br /> 〈input type="text" title="用户名" name="user" maxlength="30"/〉<br /> 〈br/〉密 码:<br /> 〈input type="password" title="密码" name="pwd" maxlength="30"/〉〈br/〉<br /> 〈do type="accept" label="发送" optional="false"〉<br /> 〈go href="main.asp" method="post" accept-charset="utf-8"〉<br /> 〈postfield name="user" value="$(user)"/〉<br /> 〈postfield name="pwd" value="$(pwd)"/〉〈/go〉<br /> 〈/do〉<br /> 〈/p〉<br /> 〈/card〉<br /> 〈/wml〉</code><p> 2) 邮件主页面</p><p> 邮件主页面主要功能为验证登陆页面传过来的用户名与密码是否正确,如果正确则显示相关的邮件操作链接(如图四),反之则提示密码错误要求重新输入(如图三)。由于某些移动设备不支持跳转,程序尽量避免使用跳转语句。</p>
<p> </p>
<p> <img src="/content/uploadfile/200805/2008053117025824.jpg" onclick="get_larger(this)" title="请点击图片查看原图" /></p><p> 图三 (登陆失败) 图四(登陆成功)</p><p> 邮件主页面源代码: main.asp</p><code> 〈% @LANGUAGE="VBSCRIPT" CODEPAGE="65001" %〉<br /> 〈%Response.ContentType = "text/vnd.wap.wml; charset=UTF-8"%〉<br /> 〈?xml version="1.0" encoding="utf-8"?〉<br /> 〈!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"〉<br /> 〈wml〉<br /> 〈card id="main" title="Sohu-PALM-MAIL平台"〉<br /> 〈p〉<br /> 〈%<br /> on error resume next<br /> user=request("user")<br /> pwd=request("pwd")<br /> Set pop3 = Server.CreateObject( "JMail.POP3" )<br /> pop3.connect user,pwd,"http://pop3.sohu.com"<br /> pop3.Disconnect<br /> if err.number〈〉0 then<br /> response.write("登陆错误,请检查用户名密码是否正确!〈br/〉")<br /> response.write("〈a href='index.asp'〉重新登陆〈/a〉〈/p〉〈/card〉〈/wml〉")<br /> response.End()<br /> end if<br /> response.write("欢迎你"&user&"@sohu.com〈br/〉")<br /> %〉<br /> 〈a href="email_title.asp?user=〈%=user%〉&pwd=〈%=pwd%〉"〉收件箱〈/a〉〈br/〉<br /> 〈a href="send.asp?user=〈%=user%〉&pwd=〈%=pwd%〉"〉发件箱〈/a〉〈br/〉<br /> 〈a href="index.asp"〉重新登陆〈/a〉〈br/〉<br /> 〈/p〉<br /> 〈/card〉<br /> 〈/wml〉</code><p> 注:</p></p><p> 〈a href="email_title.asp?user=〈%=user%〉&pwd=〈%=pwd%〉"〉收件箱〈/a〉</p><p> 由于某些移动设备并不支持session,为了更好的应用,故采用url参数传递,遗憾的是这样做安全性不高,为了提高安全性,建议对参数进行明文加密后再进行传递,在接收页面在做相对应的解密处理,当然如果你有什么更好的办法,还请发邮件指出,谢谢。</p></p>