在Director中发送E-mail

相关讨论:

http://www.soshow.org/bbs/dispbbs.asp?BoardID=54&ID=6932&replyID=&skin=1

  Director拥有非常强大的网络综合能力。通过Director可以在网页中存取数据,从服务器下载文件,甚至和CGI通信。更重要的是,利用Director不仅能够存取和监控程序的运行状态,而且当出现错误和问题时,可以及时反馈给用户,但如果想要在Director中发送email的话就有点困难了。Director并没有内置的处理email的程序,所以需要一些特殊的方法。

  本文将叙述三种在Director中发送email的方法,包括使用“goToNetPage”命令,和服务器上的CGI建立连接,以及在DirectXtras中使用DirectEmail Xtra。


  goToNetPage

  使用goToNetPage命令,并用mailto URL替代http URL,或许这是通过Director发送email消息最简单的方法,因为mailto格式很简单。

mailto:

或mailto:[email protected]

  要测试命令,在Director中打开Message窗口,输入gotoNetPage "mailto:[email protected]"并按回车键。



  如果系统配置正确,那么你所指定的email客户端将被激活,并显示一条新的消息已被发送到上面的地址(你可以用别的email地址替代)。

  通过一个询问标记符分开email地址,上述的mailto URL也能够链接到特定目标。为了使你的email客户端能够处理任何空格和特殊字符,此目标必须经过URL编码。因此,如果想要给“Hi Zac”发送一条email消息,可以使用

thisSubject = "Hi Zac"
thisSubject = os_URLEncode(thisSubject)
url="mailto:[email protected]=" & thisSubject
gotoNetPage url


  注意,在上面的例子中,并没有使用Director内置的URLEncode()函数。这个随着Director 7添加进来的函数会将字符串中的空格转换为“+”。大部分email客户端(包括很多浏览器)会将空格用“20%”代替。因此为了更恰当的选择转换,我自己编写了函数,这些函数(还有一些辅助的函数)的代码被放在样本影片中。

  作为一个非常简单的创建email消息的的例子,还有一些问题需要解决。

  第一,你无法统一指定消息主体或者任何其他收件人。因此,如果想要在添加抄送人和保留副本的同时定义消息的主体,或多或少都要依靠你的用户email客户端从mailto URL中解析出来的信息。如果你不了解用户的email客户端的话,尝试发送比“To:address and the subject”更多的数据需要冒一定的风险。

  第二,即使你能够创建一个消息,也并不能保证用户能够发送。整个mailto URL只是创建消息,用户还是要自己发送消息。

  第三,你无法监控程序的运行状况。一旦使用了goToNetPage,也就意味着你失去了对进程的控制。如果出现错误的话,你将不能得到任何来自用户的反馈,即使明知会发生错误。

  最后,利用goToNetPage处理mailto URL的效果很差。这并不是Director造成的,而是大多数浏览器和操作系统对mailto URL的支持不好。如果用户的系统配置不正确的话,经常会看到web浏览器先被打开,email客户端才被激活。更糟糕的情况是,由于浏览器错误配置,使得mailto URL无法被送到email客户端。一旦无法追踪进程,那么当这些事情发生时,没人会知道。

  总而言之,这并不是最佳的解决方案。

源码下载:

点击浏览该文件

原著:Zac Belado
  翻译:alphachi

  Server side CGI

  更好的解决方案是使用服务器端的CGI发送email,这需要在你的服务器上安装CGI。大部分的ISP都为他们的客户提供了标准的CGI,如果没有的话也可以在很多站点(例如CGI Resource Index)上找到大量的实例。由于Director内置的postNetText函数具有和标准网络命令同样的功能,所以与CGI通信是很容易的。因为涉及到一些CGI的知识(以后我们还会详细介绍),下面的例子可能有些不太好懂,我们会大概介绍一下与本文有关的CGI的基础知识。

  让我们假设你正在给一个CGI发送数据,包括“to”、“from”、“subject”、副本和消息主体。如果这些数据元素都由你的Director放映机提供,那么可以使用postNetText来传输这些数据。

toRecipient = member("toField").text
fromRecipient = member("fromField").text
subject = member("subjectField").text
ccRecipient = member("ccField").text
body = member("bodyField").text
thisURL = http://www.soshow.org/formMail.asp
propList = [#to: toRecipient, #from: fromRecipient, #subject: subject, #cc: ccRecipient, # messageBody: body]
thisNetId = postNetText (thisURL, propList)

相关讨论:

http://www.soshow.org/bbs/dispbbs.asp?BoardID=54&ID=6932&replyID=&skin=1
  postNetText和getNetText非常相似,它获取一个URL和一个属性列表(或者是一系列字符串数据),并调用一个网络ID,你可以利用这个ID来跟踪进程并返回网络的运行结果。因此任何你拥有的(或者从《与CGI通信》一文中获得的)网络代码只要作极少量修改或不作任何修改就可被postNetText调用。

  因为调用postNetText实际上会将数据发送到CGI,所以需要为其提供一个属性列表,其中包括每一个要发送到CGI的数据元素的属性。前面我们的例子涉及到CGI需要“to”、“from”、“subject”、副本和消息主体这些数据元素,因此示例代码中的属性列表为每个数据元素提供了一个符号和一个字符串,这些数据将被发送到CGI。

  你也可以将这些数据作为普通的字符串发送,但这样数据将被作为text或html文件发送,因此可能不会被大多数CGI兼容。

  使用服务器端的CGI将使你在email处理上获得更多的控制权,但也存在一些问题。

  首先,绝大多数CGI是用Perl编写的。如果你了解Perl或有权修改他人编写的Perl的话那当然很好,但如果你没有使用Perl的经验,那么修改一个Perl编写的CGI会很痛苦。

  其次,Perl脚本(和大多数CGI)在安装和运行前可能会有些问题。可能很多人不同意这个观点,但根据经验,或许专家才能使Perl配置得非常好。不过话又说回来,一旦CGI被安装和配置好了,通常运行时不会出现什么问题。

  最后,大部分易于使用的CGI都是在WEB页上使用的,因此其报告数据的方式或许并不适合在Director或Shockwave中使用。这意味着为了定制数据格式,以使其能够将消息的状态反馈给用户,将很可能不得不重写CGI的某些部分。

DirectEmail Xtra

  使用DirectXtras的DirectEmail Xtra或许是最好的解决方案。这个Xtra是跨平台的,并且也是Shockwave安全组件(点击这里观看Shockwave版本的示例影片),所以用此方法创建和发送email的方案能被广泛采用。它的使用方法很简单,而且允许在Director中定制整个处理程序。

  DirectEmail Xtra的命令格式很简单:

  *New ( Xtra "DirectEmail", string mailServer, string MailboxName, string Password )
  创建Xtra的一个新的实例

  *SendEmail ( object me, string From, string To, string CC, string BCC, string Subject, string Body, string Attachment )
  创建并发送email消息。如果此Xtra正忙于发送另外一条email消息的话,返回FALSE

  *EmailDone ( object me )
  如果email处理程序已经运行完毕,像netDone()函数一样返回TRUE

  *EmailErrorCode ( object me )
  返回因为Xtra实例运行而产生的最近一次错误的代码

  *EmailErrorMessage ( object me )
  以友好的方式返回错误信息。

  *EmailAbort ( object me )
  终止email处理程序。

  *GetUserEmailPref ( integer InfoToLocate )
  如果有相关的Internet配置安装在用户的机器上,返回用户缺省的email地址和mail服务器地址。此命令仅适用于Mac机。

  用这个Xtra发送一个email消息的步骤也很简单。



  Step 1

  你要做的第一件事就是创建一个这个Xtra的实例,并给其提供mail服务器的地址,然后它将尝试直接发送mail。也可以让用户提供,甚至由你来提供硬代码。

global gEmail
gEmail = new (Xtra "DirectEmail", "mail.somedomain.com", "", "")

  一旦创建了这个Xtra的实例,就应该将其存储在一个全局变量或目标属性里,以便迟些时候能够找到。注意,这个Xtra的最后两个参数(mailBoxName和password)在这个版本中并不能正确的使用,你只要用空白字符串填充即可。

  Step 2

  现在你需要提供要通过email传递的实际信息。在样本影片中,这些信息由包含在一系列域中的内容提供,这些内容都是用户输入的数据。

  首先,你要从域中获取数据:


messageHasErrors = FALSE
errorMessage = ""
recipients = member("To").text
fromAddress = member("From").text
mailServer = member("MailServer").text
CCRecipients = member("CC").text
BCCRecipients = member("Bcc").text
body = member("Body").text
attachment = member("Attachment").text
subject = member("Subject").text


  然后将它存储到一些比较方便的地方,比如一个属性列表,主要是为了更容易参考。

--将这些数据存储到一个正规的属性列表中
messagePropList = [#to:recipients, #from: fromAddress, #server:mailServer, #CC:CCRecipients, #BCC:BCCRecipients, #body:body, #subject:subject, #attachment:attachment]

  然后作一些测试,以确保用户输入了数据。可能也应该测试数据的有效性,以确保用户输入了有效的email地址,甚至有效的mail服务器地址。在样本影片中用isValidEmail()函数和emailValidationError()函数来实现此功能。本例中只测试了“To:”和“From:”。

if recipients = EMPTY then
  messageHasErrors = TRUE
  errorMessage = errorMessage & "You need to specifiy at least one recipient" & RETURN
end if
if fromAddress = EMPTY then
  messageHasErrors = TRUE
  errorMessage = errorMessage & "You need to an email address to send the message from" & RETURN
end if
 --验证地址是否有效
toAddressHasErrors = isValidEmail (messagePropList.to)
fromAddressHasErrors = isValidEmail (messagePropList.from)
if toAddressHasErrors then
  messageHasErrors = TRUE
  errorMessage = errorMessage & "The To: address you supplied is not valid because" && emailValidationError (toAddressHasErrors) & RETURN
end if
  
if fromAddressHasErrors then
  messageHasErrors = TRUE
  errorMessage = errorMessage & "The From: address you supplied is not valid because" && emailValidationError (fromAddressHasErrors) & RETURN
end if

  如果没有错误,将这些信息数据发送给早些时候创建的Xtra实例。

if NOT messageHasErrors then
  isOkayToSend = sendEmail (gEmail, messagePropList.from, messagePropList.to, messagePropList.cc, messagePropList.bcc, messagePropList.subject, messagePropList.body, messagePropList.attachment)
else
  alert errorMessage
end if
  
  Step 3

  现在等待程序运行完成。DirectEmail Xtra有一个emailDone()函数能够测试程序是否运行完成,这和用netDone()函数检测网络操作是否完成非常相似,只是需要用此实例中的相关参数来代替网络ID。你可以在一个exitFrame处理程序中测试这个函数,但在一个对象或行为的stepFrame处理程序中测试可能会更好。

  为了简单起见,样本影片将本文所涉及的全部处理程序都包括到了一个单一对象中。这并不意味着你也必须使用对象,仅仅因为本人喜欢在每件事里都使用对象。在一个exitFrame处理程序中测试emailDone()函数非常容易,一旦程序运行完毕,影片会跳到另外一帧。

global gEmail
on exitFrame
 --完成了吗?
  if EmailDone(gEmail) then
    go to frame "done"
  else
    member("status").text = "Waiting for results..."
  end if
end

  Step 4

  一旦mail程序运行完毕,就需要测试emailErrorCode()函数,以判断email是否已经发送成功。

emailHasErrors = EmailErrorCode(gEmail)
If NOT emailHasErrors then
  member("status").text = "Your Message was Sent!"
else
  member("status").text = "Error:" && emailHasErrors && emailErrorMessage(gEmail)
end if

  如果发送成功,emailErrorCode()函数将返回0值;如果有问题的话,返回其他整数值,代表有错误。emailErrorMessage()函数将返回一串描述错误的字符,以便将错误报告给用户。

  DirectEmail xtra的另一个特点就是拥有测试和报告的功能,而另外两种方案并不允许这么做。如果在mail处理程序运行期间用户的网络连接被中断,Xtra将报告给用户。如果用户指定的mail服务器不能使用DNS,Xtra将会报告给你并能够将此信息反馈给用户。此外,它允许你在Lingo代码中初始化和控制整个程序,这意味着你不必受困于操作系统配置问题、缺少email客户端或者CGI的某些特性。


  细节问题

  样本影片基本是按上述步骤创建的,但将此Xtra中的所有交互包含到了一个对象中。这样做有两个原因。首先,这样做使影片更加简单。除了实现基本的发送email的功能外,这个影片还有两个按钮剧本,一个检测用户提供信息有效性的函数和一个"go to the frame"的exitFrame处理程序。其次,只需很少的工作量,就可以做到大多数代码再利用。由于大部分代码都在一个对象中,所以几乎只需要简单的复制粘贴,就可以将其添加到别的影片中。

  在样本影片中,如果用户不点击发送按钮,将不会有任何事发生。一旦点击了发送按钮,sendMail()函数将测试数据。如果数据有效则创建一个属性列表,然后创建一个新的对象并切断这个对象的数据传输。此外,该对象被作为一个全局变量存储。

  该对象创建了一个Xtra的实例并将其作为属性存储,它只能在对象内存取数据。然后对象将mail数据发送给Xtra,并把自己添加到actorList中。

  在stepFrame处理程序中,对象检测email程序是否运行完毕。如果完毕,再检测是否有错误发生并将其报告给用户。然后对象删除这个DirectEmail xtra的实例,并调用一个外部处理程序stopEmail()以删除这个对象。

  总结

  在上面讨论的三种方案里,真正有使用价值的是服务器端的CGI和DirectEmail Xtra。gotoNetPage看起来好像是一个快速简便的解决方案,但实际上它有很多潜在问题,比如无法控制和无法测试。如果你有编写CGI的经验,或者有权使用他人编写的CGI,或者有权修改他人编写的CGI以使其更适用,那么使用服务器端的CGI也是一个可行的方案。但如果你想创建基于Director的自定义的email解决方案,DirectEmail Xtra或许是最好的。

相关讨论:

http://www.soshow.org/bbs/dispbbs.asp?BoardID=54&ID=6932&replyID=&skin=1

你可能感兴趣的:(在Director中发送E-mail)