如果我们将每个页面都分别提交给FrontPage的 email 向导或CGI 的email 程序,那么可怜的订单书写人就要为订单的每一页都收到一个单独的邮件信息。当然我们可以通过session变量、隐藏域或查询字符串将订货数据从一页传递到另一页,但是在内存中储存这些数据会造成应用程序不平衡,另外潜在地需要大量的脚本。而且当页面上的域变化时还必须要修改脚本代码,所以代码不太能够再利用。 如果能够写出一套脚本可以用在所有这些订单页面中,只把HTML页面的设计留给WEB设计者,那就太好了。 一个简单的答案是,将每个页面中的数据保存在一个文件中,然后将所有这些文件连接起,再将之用Email方式发送给订单书写人。这种方法另外还有一个好处是如果愿意可以在硬盘上保持临时文件,那么在晚些时候用户可以继续一个未完成的订单。最好的一点是,执行这一办法不需要第三方组件,而只需要session变量,ASP脚本和Scripting.FileSystemObject 对象。 首先要为这些单独的页面数据文件确定唯一的名字,这样在订单结束时可以将它们放在一起,并且不会被应用程序中的其它文件所覆盖。同时,需要从单个session变量表示的文件进行聚合中,这样就不会偶然将一个旧session中的数据包含到当前的订单中。 由IIS所提供的Session变量("SessionID")在一个Session过程中在网络服务器上是唯一识别的,但是到了后面,Session就可以被复制。(事实上,SessionID在以后会话Session时总是要被复制的,SessionID存储在客户机的一个cookie 中。当网络服务器从客户机中接收到一个过去会话的SessionID时,若它没有被另一个活动会话所使用,就使用相同的值,这样就不用向浏览器发送另一个cookie了,有关的信息可以参见微软MSDN上的Managing Sessions。 为了唯一识别session,我们要创建一个自己的session识别器Session("SessionToken"), 使用时间考验的方法: 通过将SetSessionToken 封装成函数,可以轻易地修改算法来生成一个session 标志,而不用影响代码的其它部分。在第一页订单的顶端将调用SetSessionToken。 每一页都要有一个唯一的页码,要将它附加到session 标志变量上去产生文件名。给页面使用任何一种标志都可以,但是在这里的应用程序中,页面必须要按照输入的顺序被输出,所以就使用一个捕捉这一顺序的页码。跟前面一样,将这个文件名算法封装到一个函数中,以后修改起来就很容易了。 在订单第一页后面每一页的顶端,都调用WritePage函数将从前一页提交的数据写入文件。最后一页之后也调用这个函数。 要记住每一页的数据都由后面一页来负责写入文件,所以第二页必须知道它是跟随第一页的,依次类推。用一个session 变量 CurrDataPage把当前表单数据页码从这一页的开始带到下一页的WritePage() 调用中,而不是在调用中使用每个页码的硬编码。一会儿就能看到,将所有页码结合起来的程序要知道最后一个页码是什么,所以使用一个子程序来给CurrDataPage 赋值,同时查看它是不是最后一页的页码。 数据的最后一页将被提交给一个确认页,这是任何电子商务站点上的标准步骤。我们的情况需要一个确认页,以提供一个机会来写出最后一页订单的数据,并建立传输数据的文件。(如果不想用一个确认页,也可以用一个脚本在结尾重定向到纯ASP页。) GetAllData 函数将返回在不同页中输入的所有数据元素的组合值。 要注意GetAllData 函数在每行结束时使用回车换行符(carriage-return)组合,而不是用HTML的< BR >元素。如果在确认页上用inline文本或HTML显示所有订单数据,这就会是一个很长的页。如果这么做,就会将用户接口的关键部分“用户响应时用的按钮和控件”都推到屏幕的可视部分之外,这样,这个页面就远远不能说是很注意用户友好性。要使页面不是太长,可以在一个滚动文本框中显示订单数据,而不是使用全部的HTML。要回顾这些数据时,用户必须使用滚动条,但是他们不必滚动整个浏览器窗口。 通过在< TEXTBOX >元素的VALUE 子句中嵌入一些ASP脚本,可以显示订单的情况: onfocus事件的处理并不是交给ASP,而是由客户端的javascript执行。用< TEXTAREA > 元素作为滚动显示框 优点和缺点 任何一种工具或方法的价值取决于试图解决的问题和特定的环境。现在来看看这种方法的正反两面: 优点 ○ 不需要第三方控制; ○ 不需要任何客户端表单处理(除了确认页上一点javascript 以外,而那也是可以选择的); ○ 脚本与HTML很好地分离。多数脚本代码位于页面的顶端和底部; ○ 最小的内存需求。 缺点 ○ 需要更多的磁盘空间,至少是临时的; ○ 更多的磁盘输入输出,在轻型-中型服务器负载下,可能会比在内存中处理的解决方法速度慢; ○ 使用了Session变量(更多的细节请看使用Session变量的优点与缺点)。 结论 这个处理多页面表单的方法很容易理解,执行起来也很直接,但是有许多地方明显地需要加强。首先,可以用另一种方法储存临时数据,可能是数据库。另一种可能是使用一个XML 文件,这样就可以免除每一页都需要一个单独的数据文件的需要,而且可以利用Microsoft XML 分解工具:IE5 和 XMLDOM API。XML文件更容易被其它应用程序使用,也更容易文档化。 尤其是在一个多服务器的环境中,我们也许会选择用Session 对象来管理session 。在session变量的管理技术方法上有两篇很好的文章,是Jeff Benson的 "Serialize Your Session with a Homegrown State Management Component for ASP", 和Craig McQueen的 "Maintaining User State with the Active User Object (AUO)"。 最后,我们也许想要改变创建session识别号的方式。把用户帐号与订单的日期和时间结合起来,就允许用户重新开始一个以前未完成的订单。或者也可以把以前的session识别号储存在一个cookie 中并重新装载到下一个session 中。 点击此处下载本文相关文档。 |