perl教程019

Perlæ•™&am - 下载 第 19 学 复 杂 窗 体 We b

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: 下载 第 19 学时 复 杂 窗 体 We b 上的窗体不只是简单的单页面窗体。有时窗体要跨越若干页。这些复杂的窗体以调 查、查询和购物车等应用程序的形式出现。 这些比较复杂的窗体需要使用某些不同的编程技巧,本学时你将要学习这些技巧。 在本学时中,你将要学习: • 如何创建多页窗体。 19.1 复杂的多页窗体 使用CGI程序来编写复杂的多页窗体时,你会遇到一个特殊的编程难题。 Web浏览器与Web 服务器之间的连接根本不是一个持久的连接。 Web浏览器与服务器建立连接,检查 Web页,然 后便断开与 Web服务器之间的连接。在服务器与你的 Web浏览器之间并不保持不间断的连接。 更为复杂的是:浏览器每次与 Web服务器连接时, Web服务器并不认为该浏览器预先访问 过该站点。服务器并不每次都能很容易地识别该浏览器。 类似的一种情况是:图书馆的读者与没有记忆力的图书馆管理员之间进行谈话,读者每 次只能向管理员提出一个问题。 读者向图书管理员借阅一本书,比如关于亚利桑那州的一本书,图书管理员可以检索这 本书。图书管理员之所以能够检索这本书,是因为这个请求很容易满足。但是读者不能要求 借阅同一个专题的另一本书。图书管理员不能记住上一个借书请求,因此他无法借给你同一 个专题的另一本书。如果借书的请求改为“给我另一本关于亚利桑那州的书” ,图书管理员仍 然无法满足读者的要求,因为他检索的书可能与第一次检索的这本书一样。 若要检索同一专题的第二本书,惟一的办法是说: “我需要另一本关于亚利桑那州的书, 我已经有了一本名叫《在亚利桑那州定居》的书” 。这个借阅请求带有足够的能够说明问题的 信息,使图书管理员能够知道什么应答是不适当的。 为We b页编写多页窗体,也可以使用同样的解决办法。每个问题 / 答复会话必须包含足够 的信息,使 We b服务器能够知道它需要做什么。你可以用几种不同的方法来创建这样的会话, 其中的一种方法,即使用隐藏的 HTML 域,将在本学时中介绍。 19.2 隐藏域 要使 Web窗体能够“记住”信息,最容易的方法是使用隐藏域,将以前的信息嵌入 Web窗 体。隐藏域是HTML窗体的组成部分,它使域和值成为 HTML的组成部分,但是在显示窗体时, 窗体中并不出现这些域和值。在 HTML中,这些域和值编写为下面的形式: 如果将上面的 H T M L 代码放入一个窗体,新的名字( f u l l n a m e ” “ )和值( Pink Floyd ” “ ) 将成为窗体的组成部分。如果该窗体被提交给一个 Perl CGI 程序, p a r a m 函数将返回一个关键 字和隐藏域的值。 218 使用第三部分 将Perl 用于 CGI 下载 在线商店 如果要举一个如何使用隐藏域的例子,可以看一看在线商店,它使用一系列的 We b 页, 使人们能够根据在线目录来选购商品。目前,我们只是向你介绍复杂窗体的运行情况,在本 学时后面部分的内容中,要介绍另一个复杂的窗体,它包含用于创建一个在线调查的代码。 如果不能实现某种形式的安全 We b 事务处理,那么请不要使用这个在线 商店的例子,请注意,这个例子并不包含任何真实的个人信息,如电话号码 或信用卡号码等,因为隐藏域就像正规的 H T M L窗体,它根本不具备任何安 全性。 图19-1所示的在线商店第一页显示了该商店的商品清单。 图 19-1 在线商店的第一页 当用户单击 Go to Store (去商店)按钮时, CGI 程序接收来自窗体的值,然后显示完整的 目录,如图 19-2 所示。 图 19-2 显 示在线商店的商 品目录 第二页显示完整的目录。当第一页(带有商店拥有商品的目录)提交时, CGI程序接收各 个值,然后当它为完整的目录输出 HTML 时,它将商品的指定数量作为隐藏域放入新窗体。 每当 C G I程序接收来自 H T M L窗体的值时,新页将包含隐藏域中的旧值,以及普通窗体元 素中的新值。 采用这个方法,你可以避免“健忘的图书管理员”存在的问题,当提交完整目录的窗体 时,窗体中的隐藏域便提醒 CGI程序从第一个窗体中选定哪些项目以及从当前窗体中选择哪些 项目。 如果需要第三页,前两页中的值可以作为隐藏域存放在第三页上,如图 19-3所示。 关于 H T M L 页上的隐藏域,有几个问题应该加以说明。首先,隐藏域中的值是任何人都 能够查看的。若要查看这些值,用户只需要查看该页的 HTML源代码。大多数 Web 浏览器都配 有一个选项,可以用于查看 HTML源代码。 其次,隐藏域中的值可以由远程用户进行修改,如果他们确实想要这样做的话。若要修 219 第19学时 复 杂 窗 体使用 下载 改隐藏域的值,可以使用修改后的 We b浏览器,或者使用 H T T P 人工提交该窗体。例如,在线 商店不应该将价格存放在隐藏域中,它只能存放数量。 CGI程序应该在需要显示价格时才查看 价格。 图 19-3 在 线商店的发货信 息 当你设计窗体时,看一看别人是如何设计窗体的,这将会对你有所帮助。 这样你也会对他们是否使用隐藏域来保存信息这个问题有所了解。大多数 Web浏览器都有一个 View Page Source (查看页源)选项。你应该将这个选项 用在任意窗体上,以了解它是如何形成一个整体的。但是不要拷贝这个窗体, 大多数时候,拷贝会侵犯窗体的原开发人员的版权。 19.3 多页调查窗体 调查窗体是查找跨越若干不同的 Web 页窗体的常见地方。有时这些窗体太长,一个 Web 页 放不下,它们通常可以分成不同的类别。 接着,简单的多页 Web调查窗体可以用于查找关于你的个人信息的各个方面。这个调查窗 体可以展示 4个不同的Web页,并且可以改为支持你需要的任何数目的 Web页。这4个Web页是: • 第 一页用于提出一系列的一般问题,有时它们可以用来查找你拥有哪些种类的个人信 息。 • 第 二页用于提出一些关于你的习惯爱好的特殊问题,还有一个根据第一个调查页提出的 问题。 • 第三页是供你输入你的名字和对调查的说明的 Web页。 • 在调查完成后输出的一条感谢你的消息。 相同的 C G I 程序可以用来执行所有这 4 个功能。它决定了哪一页用来打开下一页。这是根 据刚才显示的这一页来决定的。程序清单 19-1显示了调查程序的核心。 通过包含代码 use CGI::Carp qw (fatalsToBrowser), 你的 CGI程序的 die()消息(它 通常被写入 We b 服务器的日志文件)将作为 We b 页的组成部分来输出。当你 编写更长的 CGI 程序时,它将有助于程序的调试。 220 使用第三部分 将Perl 用于 CGI 下载 调 查的结果保存在一个文本文件中,但是该程序根本不显示该结果。该程序只不过进行 调查结果的收集和存储。你必须编写另一个 CGI程序,以便显示调查的结果。 程序清单 19-1 调查程序的第一部分 第6 ~ 8 行:在调查过程中,每个 H T M L窗体都包含输入域。每个输入域的名字都出现在这 个数组中。 save()函数和 repeat_hidden()函数将在以后使用这个数组。 第1 2 ~ 1 3 行:如果不将任何参数传递给该 C G I程序,也就是说,它没有作为窗体发送的结 果来加载,那么就调用 page_one ()函数来输出调查窗体的第一页。 第14~17行: 如果名叫 pageone 的HTML窗体参数被传递给这个 CGI程序, 便调用 page_two ) ( 函数。如果传递的参数是 pagetwo ,便调用函数 page_three。 第 1 9 行:如果 H T M L 窗体参数传递给个 C G I 程序,但是传递的参数不是 p a g e o n e 或者 pagetwo,则调查完成,其结果被保存,并在 survey_done()函数中输出感谢你的消息。 每个 We b 页上的 s u b m i t 按钮都提供了一个关于下面应该加载哪一页的线索,你可以在图 1 9 - 4 中看到这个情况。由于 s u b m i t按钮的名字作为一个参数被传递给 C G I程序,因此它可以用 来显示刚刚提交给程序的是 Web页的哪个版本。 程序清单 19-2是调查程序的第二部分。 程序清单 19-2 调查程序的第二部分 221 第19学时 复 杂 窗 体使用 下载 图 19-4 哪 个按钮用于执行 浏览器 浏览器 哪个操作的示意图 下一页 上一页 1. 将参数 2. CGI程 “pageone” 序输出 发送给CGI 程序 0. 没有发送任何 参数。第1页 输出 6. 最后一页输出 CGI 程序 3. 将参数“pagetwo” 发送给CGI程序 4. CGI 程序输出给 浏览器 谢谢你 5. 将参数“pagethree” 发送到浏览器 第 2 2 ~ 2 4 行是个 P e r l 新结构,你以前没有看到过,它称为“ 提交结果 here document ” h e r e 。 d o c u m e n t 使你可以设定一个跨越若干行的字符串,它包含其他的引号,可以像一个普通的双 引号那样来运行。若要开始编写一个 here document ,你可以使用 < < ,后随一个单词。这个引 号的内容就继续下去,直到在一行的开头再次出现该单词为止,如下例所示: 用于标识 here document 开始的单词,即上面这个代码段中的 E N D _ O F _ Q U O T E ,或者程 序清单 19-2中的 END_PAGE_ONE ,后面必须跟一个分号。在 here document 的结尾,该单词必 须出现在第一列的开头,并且后面不能有任何字符,如空格或分号。在 here document 内,变 量像它们在普通双引号字符串( )中那样展开,因此在 here document 中,必须慎重使用 $和 “” @字符。 使用 here document 时,可以将大量的 HTML代码嵌入你的 Perl程序,而不会夹杂许多引号 和多个 print 语句,从而造成混乱。 程序清单 19-2中的函数只是用来输出一个 HTML窗体。 FORM>标记并不包含动作和方法。 < 222 使用第三部分 将Perl 用于 CGI 下载 当没有设定 < F O R M > 的a c t i o n 属性时,当前的 C G I 程序(即产生窗体的 C G I 程序)将在提交窗 体时重新加载。当不提交 method属性时,便使用默认方法 GET。 请注意,窗体上的提交按钮的名字是 p a g e o n e 。当该窗体被提交时,一个称为 p a g e o n e的 参数将被发送到该 C G I程序,它的值并不重要。被提交的这个参数将提示 C G I 程序加载第二个 Web 页。 程序清单 19-3是CGI程序的第三部分。 程序清单 19-3 调查程序的第三部分 第 4 7 行:正如第 4 6 行中的注释所表示的那样,这一行中的函数用于输出作为隐藏域的该 窗体的所有域的值。数据 @ s u r v e y _ a n s w e r s包含 H T M L窗体上所有可能的“ n a m e =”值。当第 一次运行时,大多数域将不存在,因为调查的这些部分尚未填入相应的的值。 第 4 8 ~ 4 9 行: @ s u r v e y _ a n s w e r s 中可能的每个参数均被检查,每个参数均被定义。输出 HTML标号 <INPUT TYPE=hidden> ,用于存放当前窗体上的值。 第56行:这个函数用于输出调查的第二页。 第5 7 ~ 6 0行:这个函数在调查的第二页中调用。如果调查的第一页填入了正确的值,那么 param ( pettype’ ‘ )将保存 dog 或cat,这个值将存放在 $pet中。如果被调查人跳过了这个问题, 同时 param( pettype’ ‘ )没有定义,那么就改用 goldfish。 223 第19学时 复 杂 窗 体使用 下载 第61~76行:来自第一页的 HTML 窗体参数均转入该窗体,作为其隐藏域。 如果你在这时查看调查窗体,即它的第二页,那么第一页的所有答案均作为隐藏域存放 在第二页的结尾处。程序清单 19-4显示了第三页的代码。 程序清单 19-4 调查程序的第四部分 函数 p a g e _ t h r e e ()是非常明了的。它只是输出窗体中的一个文本框和一个文本区域。在 结尾处,它再次调用 r e p e a t _ h i d d e n ()函数,以便将所有隐藏域放入调查窗体的第三页。程 序清单 19-5显示了 CGI调查程序的结尾部分。 程序清单 19-5 调查程序的最后部分 224 使用第三部分 将Perl 用于 CGI 下载 第 9 6行:调用这个函数只是为了输出感谢你的消息。当某人遍历调查窗体的 3 个页面后, 这样做总是一件很好的事情。然后调用 save()函数。 第1 0 3 行:这里的 s a v e()函数几乎是第 1 8 学时中的 s a v e 函数的复制品。它用 g e t _ l o c k() 将调用文件锁定,再使用类似 r e p e a t _ h i d d e n ()中的方法写入对问题的答案,然后用 release_lock ()函数对文件解锁。 你可以随意修改这个调查程序,以适应你自己的需要。它的设计非常灵活,并且可以用 于许多不同的目的。 19.4 课时小结 在本学时中,你学习了如何创建多页 We b 窗体的方法。当你进行这项操作时,了解到程 序需要解决的几个问题,最重要的是要记住从一页转到另一页时会出现的一些情况。你还学 会了如何使用隐藏域将信息存放在服务器无法记住的 We b页上,然后就可以使用隐藏域来创 建框架调查窗体了。 19.5 课外作业 19.5.1 专家答疑 问题: HTML窗体难道一定是如此不顺眼吗? 解答: 本书中介绍的这些窗体是简单的、缺乏特色的框架式的窗体,有的人称它们是不 顺眼的窗体。本书的目的是教你进行 P e r l 和 C G I编程,而不是教你如何使用 H T M L 。实际上, 本书中讲到的大多数 H T M L程序与标准无关,并且它是不完整的,它没有使用 < H E A D > 标记, 和 < H T M L > 标记,也没有 D T D标题。通过提供基本的 H T M L,我想你能够对它进行修改,使 之符合你的需要。 前面讲过,给窗体增色的好办法是查找 We b ,寻找你喜欢的窗体。通过查看源代码,你 就会对如何将这些 Web页组合在一起有个大致的了解。 问题: 我看到这样一个出错消息: Can’t find string terminator “ xxxx” anywhere before EOF at ... 。这是什么意思? 解答: 这个错误是因为在程序的某个位置上有一个左引号,但是没有匹配的右引号而造 成的。当你使用“ here document ”时,这意味着无法找到你给“ here document ”做上结尾标 记的单词。它的格式如下: 在上面这个例子中, here document ”开头和结尾的单词 MARK必须完全相同。结尾的单 “ 225 第19学时 复 杂 窗 体使用 下载 词这一行上,它的前面不能有任何东西,后面也不能有任何东西。 MS-DOS和Windows的文本 编辑器有时并不在程序的最后一行的后面放上行尾符。如果你的“ here document ”以文件的 结尾为结束,请在它的后面放上一个空行。 19.5.2 思考题 1) 为了使你的程序能够记住很长的多页 Web事务处理,你需要使用 a. 数据库和 cookie 。 b. 隐藏的 HTML窗体域。 c. 隐藏的 HTML窗体域、 cookie 和数据库的某种组合。 2) 使用 HTML的<FORM> 标记时,如果不带 action属性,那么它将 a. 无法运行。 b. 导致 submit按钮使用原先生成 Web页的 CGI程序。 c. 导致 submit按钮重新加载当前页。 3) 上面介绍的调查程序有一个小错误,是什么错误? a. print<<EOP ;它在程序清单 19-2 中是个无效语句。 b. HTML 不完整,因为它不带 <HEAD>标记和类似的标记。 c. 调查程序没有输出结果。 19.5.3 解答 1) 答案可以是 b或c。你可以只使用隐藏的 HTML域,也可以只使用 cookie。如果只使用数 据库,那是不行的。 2 ) 答 案是 b 。重新加载当前页将会删除当前窗体的所有答案。如果没有 a c t i o n 属性, <FORM> 标记将把当前页的 URL用作替换 URL。 3) 答案是 b。print<<EOP;肯定是个有效的语句,它称为“ here document ” 。选择 c是不正 确的,因为程序不是使用该方法设计的(参见“实习”这一节) 。 19.5.4 实习 • 编写一段 C G I 程序,用于显示调查的结果。也可以创建一个表格,以下面的形式显示这 些结果: 猫/狗 拥有一只 夜间活动 服装 被谁丢弃 旅行者 有危险吗 猫 两者之一 狗 否 金鱼 是 是 否 否 普通 专用 普通 教授 船长 玛丽 -安尼 是 否 是 是 否 是 • 补充问题,编写一个 CGI程序,将调查结果汇总成下面的形式: 猫/狗的比例 猫 40% 狗 45% 其他 15% 拥有该宠物的人 猫 20% 狗 15% 金鱼 30% 无 35% 是 35% 否 40% 的比例: 夜行者: ...
View Full Document

This note was uploaded on 11/27/2011 for the course CS Perl taught by Professor Guo during the Spring '09 term at Xiamen University.

Ask a homework question - tutors are online