一、为什么要使用CGI?
随着全球资讯网(World Wide Web,WWW)的兴起,网络从平淡的文字世界进入了影音声光的新纪元。同时也引进了新的阅读方法,一种有别传统循序式的阅读方法━Hype r Text。让人们能够直接从有兴趣的主题切入,并且在其间相互跳跃、链结,以取得所想要的资料。也因此带动了网络人口的激增以及无限的商机,所以在商业应用上这是一个值得开发的空间。
但是这样的方式却缺少了一个商业应用上一个重要的特性,那就是━互动性。而CGI的出现正是为了弥补其不足!有了CGI功能的加入可以使得W WW的环境不仅有单向的资讯浏览,更可以有双向的互动。若说CGI的发展是WWW能受广大使用者喜爱的最大原因是不为过的。
事实上,CGI的应用相当的广泛,可以借助与其它系统的结合而增强WWW Server的功能。例如∶与数据库管理系统(DBMS)结合,便是一种最常见,而且是最具扩充性的方式。因为经由不同的数据库,可以使WWW Server提供或者是记录多样化的资讯。
同时,也可利用CGI制作登录(Login)系统,将具有机密性的资料,以密码的方式加以保护。不但省去了系统过开放的困扰,也可以有效的管理使用者。更进一步,可以记录使用者的使用情形,以便加以计费或者是在网络上进行电子交易。
因此,如果要将商业应用在WWW上,CGI势必是不可或缺的一环。以下我们将会以和 管理系统结合为核心,逐步介绍何谓CGI、CGI如何输入资料、CGI如何工作以及CGI怎么输出资讯回给使用者,并且在最后附上几个CGI应用的范例,让您了解并且实作C GI。 二、什么是CGI?
2-1 CGI简介
CGI是Common Gateway Interface的简称。其主要的功能是在WWW环境下,藉由从客户端传递一些讯息给WWW Server,再由WWW Server去启动所指定的程序码来完成特定的工作。所以更明确的说,CGI仅是在WWW Server上可执行的程序码,而她的工作就是控制讯息要求而且产生并传回所需的文件。
使用CGI,你的Server可以读取并显示在客户端无法读取的格式(像是SQL DataBase)。而且可以像闸道(Gateway)一样,在伺服端和客户端之间,产生客户端所需要的讯息。基本上,在此种主从式(Client/Server )的环境之下,其IPC(Inter Process Communication)的协定是利用讯息传递及记忆体分享(环境变量)的方式来完成。CGI有其特定的写法及规格,必须遵守其原则,方可达到主从端资讯交流的目的。
2-2 CGI的输入输出
CGI可以使用在很多方面,大部份是控制ISINDEX和FORM的需求,亦即ISINDEX和FORM最常被使用作CGI的输入介面。但也有利用链结(LINK) 的方式来呼叫所要执行的程序,通常是在使用者的资讯已固定,或是为达成某种单一目的而使用。而使用链结方式其程序执行所需的参数是以G ETMETHOD的方式含在URL中传入,亦即CGI程序在发展时必须使用GETMETHOD的方式来读取参数。在第四节,我们将会详细介绍传递参数的方法。
输出的部分则大部分是利用程序来产生虚拟文件,也就是文件并不是储存Server的储存媒体中,而是由程序建构出来的,浏览程序结束之后文件即不再存在。大部分的文件格式是超本文标示语言( HTML)或是文字文件。也有利用程序链结到另一份文件,或是只记录使用者输入资讯而不做输出。
下面是常见输入输出的例子∶
转换您的系统参考手册变成超本文标示语言(HTML)的格式,接着将结果送给客户端。
当做WAIS和ARCHIE数据库的界面,将结果转成超本文标示语言(HTML)的格式送给客户端。
允许使用者透过HTML FORM和附加的CGI解码来回给你的Server。
在下面各节,将会进一步说明有关这一部分的使用方法,或是简单的范例。
2-3 CGI可用的程序语言
至CGI要使用何种程序语言来达成?从前面的说明可以知道,CGI仅是在WWW Server上可执行的程序码。是故,只要是您的WWW Server以及WWW Server所在的操作系统可执行的程序语言皆能使用在CGI上。以下列出几种较常在CGI中使用的语言∶ C/C++、Perl、THE BOURNE Sh*ll 、THE C Sh*ll 、TCL、Visual Basic、AppleScript。
这些程序在完成之后要放置何处?事实上,不同的WWW Server有不同的规定。以HTTPS为例,她只执行扩展名为EXE的文件,且程序不能为图形介面(GUI)的程序。而程序只要放置在指定文件的树状目录中任一位置即可。但是值得注意的是,大部分的W WW Server尤其是UNIX上的WWW Server,都将CGI程序放置在一共同的指定目录之下。所以在放置CGI程序时,请先参考您的WWW Server手册。
三、CGI的输入介面
在一个完整的系统中,输入介面是直接和使用者接触的第一线。所以输入介面,在整个系统中扮演着举足轻重的地位,输入介面的好坏将直接影向系统的成败。好的输入介面可以弥补系统设计上的某些缺陷,但是要如何设计出一个好的输入介面呢?第一步应了解手边究竟有哪些修缮门面的工具!在这一节中,我们将为您介绍C GI的主要输入介面,让您做好成功的第一步。
在CGI中较常见的输入介面有ISINDEX和FORM两种,详细内容分述如下∶
3-1 ISINDEX
ISINDEX是一个特殊的标签,使用的方法如下∶
--------------------------------------------------------------------------------
可以搜索该索引。请键入要搜索的关键字:
--------------------------------------------------------------------------------
其中URL为想要执行的程序之所在位址及文件名。
如此会使浏览程序产生一个输入的视窗,当使用者完成输入按下ENTER键后,Server会执行参数ACTION中指定的程序。
--------------------------------------------------------------------------------
可以搜索该索引。请键入要搜索的关键字:
--------------------------------------------------------------------------------
常见的用法是与WAIS Server结合,或是做文件案的搜寻。本节的重点将放在FORM的实作上,所以我们在这里不对ISINDEX做详细的介绍,如有兴趣请自行参考相关资料。
3-2 FORM
FROM在CGI中是最常被使用的输入介面,虽然并不十分完美,但却是目前WWW中最强大的输入工具。FORM是由一组相关连的标签所组成,使用方法就像其它标签一样。在F ORM中提供了我们多种输入资料的工具,例如文字输入区(Text)、下拉式表单(SelectBox)、按钮(Button)、选择钮(RadioButton)等等。
就目前所定义的标准中,FORM的标签可分为三大类∶、以及。下面的例子是FORM的一个概观∶
<br>
<br>
<br>
--------------------------------------------------------------------------------
<br>
<br>
INPUT标签∶
<br>
<br>
<br>
←TYPE:TEXT
<br>
←TYPE:PASSWORD
<br>
这是确定纽1←TYPE:CHECKBOXCHECKED
<br>
这是确定纽2←TYPE:CHECKBOX
<br>
这是选择纽1←TYPE:RADIOCHECKED
<br>
这是选择纽2←TYPE:RADIO
<br>
←TYPE:SUBMIT
<br>
←TYPE:RESET
<br>
<br>
<br>
SELECT标签∶
<br>
<br>
这是选项1 这是选项2 这是选项3
<br>
<br>
<br>
TEXTAREA标签∶
<br>
<br>
这是文字输入区
<br>
<br>
<br>
--------------------------------------------------------------------------------
<br>
<br>
接下来,我们将依这三大类以及FORM的基本标签做介绍。
<br>
<br>
3-2-1 FORM 标签
<br>
<br>
使用格式如下∶
<br>
<br>
<FORMMETHOD="POST/GET" ACTION="URL">...</FORM>
<br>
<br>
FORM这个标签是FORM的基本标签,所有与FORM有关的标签必须要放在<FORM>与</FORM>这标签之内。如果没有将与FORM有关的标签放在& lt;FORM>与</FORM>这个标签之内,则这些标签将不会产生作用。
<br>
FORM的参数解释如下∶
<br>
<br>
ACTION 是指定当使用者完成输入并将资料传回Server时,Server会将资料送入的位址;如果这个参数没有被指定时,FORM所在超本文标示语言(H TML)文件的URL将成为内定值。
<br>
METHOD 是指定使用者输入的资料会以何种方式传回给Server。
<br>
GET 是CGI内定的传输方法,使用者输入的资料会以含入URL的方式传回。
<br>
POST 此种方式有别GET将使用者输入的资料含入URL的方式。在程序端,资料会以STDIN的方式被接收。
<br>
ENCTYPE 这个参数只有在METHOD被设定为POST时才会产生作用,其作用是将使用者输入的资料加码传回。
<br>
<br>
3-2-2 INPUT 标签
<br>
<br>
使用格式如下∶
<br>
<br>
<INPUTTYPE=Type Name NAME=ValName VALUE=Value>
<br>
<br>
其参数如下∶
<br>
<br>
TYPE 设定使用输入的方法。输入的方法一共有下列数种∶
<br>
TEXT 文字输入区。这是内定值。 ·PASSWORD--基本上和TEXT是相同的。只是专门提供给文件阅读者输入密码之用。不管输入什么字,在画面上都只能看到「*」这个符号。
<br>
CHECKBOX 选择方块,不是ON就是OFF。
<br>
RADIO 选择圆扭。和CHECKBOX不同的是,选择圆扭通常成群出现,并且在这群选项中只能选择其中一个。
<br>
SUBMIT 也就是按钮(Button)。文件阅读者会在画面上看到一个按钮。一旦按下这个按钮,浏览程序(Browser)就会把这个FORM上文件使用者所输入的一切资料传回给W WW Server做处理。
<br>
RESET 它的外观和SUBMIT相似,不过一旦文件阅读者按下它,这个FORM上面的所有输入工具的值都会被清除,或者是回到初始值。
<br>
HIDDEN 这个TYPE将不会出现在FORM上,而是隐藏在FORM之下。其目的是为了将使用者不需要知道而程序流程上却需要的资讯记录在FORM上,以便追踪使用者现在的使用状况。
<br>
IMAGE 在FORM上会如IMAGE标签一样显示图形,其功用和SUBMIT一样会将使用者所输入的一切资料传回给WWW Server。而IMAGE本身会以滑鼠点下的X和Y座标传回,这个座标是以图的左上角以原点向右以及向下增加。
<br>
NAME 定义传回的变量名称。除了SUBMIT与RESET型态不需NAME外,其馀皆一定要有,因为如此程序才能分辨不同的资料。
<br>
VALUE 配合不同的TYPE有不同的意义,对TEXT或PASSWORD输入型别而言,是设定输入区域之内定值。对RADIO或CHECKBOX也是指定选项之内定值(O N或是OFF),不过必须连CHECKED这个参数一起使用才有效。对SUBMIT或RESET输入型别而言,其VALUE的值将会变成按钮上的文字。
<br>
CHECKED 前面已提过这个参数只对RADIO或CHECKBOX之输入型别有效,有内定圈选之意。
<br>
SIZE 针对TEXT或PASSWORD输入型别,可以定义输入区域的大小,如果没有指定输入区域大小时,则内定的大小为20个英文字元的长度。
<br>
MAXLENGTH 只对TEXT或PASSWORD输入型别有效,用来限制文件阅读者输入字串的最大长度。若没有指定MAXLENGTH大小,则内定值为无限大。
<br>
SRC 这个参数只用在IMAGE中,用来指定所用图形的URL。
<br>
<br>
请参见底下的范例∶
<br>
<br>
<br>
--------------------------------------------------------------------------------
<br>
<br>
<H3><Palign=center>快捷线上邮购公司杂志订购服务</P></H3>
<br>
<Form>
<br>
<P>请输入您的会员代号∶
<br>
<INPUTTYPE=TEXT NAME="MemberID"SIZE=10></P><P>请输入密码以确认身份∶
<br>
<INPUT TYPE=PASSWORD NAME="Password"MAXLENGTH=8></P> <P>请选择您的付款方式∶</P><OL>
<br>
<br>
<LI><INPUT TYPE=RADI ONAME="Pay" VALUE="现金" CHECKED>现金 <LI><INPUT TYPE=RADIO NAME="Pay"VALUE="VISA Card">VISA Card <LI><INPUT TYPE=RADIO NAME="Pay" VALUE="Master Card">MasterCard
<br>
<br>
</OL> <P>请选择您要订阅的杂志名称∶</P> <OL>
<br>
<br>
<LI><INPUT TYPE=CHECKBOX NAME="Magzine"CHECKED>天下
<br>
<LI><INPUT TYPE=CHECKBOX NAME="Magzine">远见
<br>
<LI><INPUT TYPE=CHECKBOX NAME="Magzine">中国生产力
<br>
<LI><INPUT TYPE=CHECKBOX NAME="Magzine"CHECKED>广告
<br>
<LI><INPUT TYPE=CHECKBOX NAME="Magzine">美丽佳人
<br>
<LI><INPUT TYPE=CHECKBOX NAME="Magzine">哈泼时尚
<br>
<INPUT TYPE=SUBMIT VALUE="以上资料正确无误"> <INPUT TYPE=RESET VALUE="清除刚才所有输入的资料">
<br>
<br>
</Form>
<br>
<br>
使用浏览程序(Browser)来看看结果∶
<br>
<br>
快捷线上邮购公司杂志订购服务
<br>
<br>
请输入您的会员代号∶
<br>
请输入密码以确认身份∶
<br>
请选择您的付款方式∶
<br>
<br>
现金
<br>
VISA Card
<br>
Master Card
<br>
请选择您要订阅的杂志名称∶
<br>
<br>
天下
<br>
远见
<br>
中国生产力
<br>
广告
<br>
美丽佳人
<br>
哈泼时尚
<br>
<br>
<br>
<br>
--------------------------------------------------------------------------------
<br>
<br>
3-2-3SELECT标签
<br>
<br>
使用格式如下∶
<br>
<br>
<SELECT NAME=ValName SIZE=ScrollSize>
<br>
<br>
<OPTION SELECTED>选项1
<br>
<OPTION>选项2
<br>
<br>
</SELECT>
<br>
<br>
这个标签提供下拉式表单或者是卷动式表单,让使用者可以从表单中选择一个或多个项目。表单是以<SELECT>开始,表单中每一个选项以& lt;OPTION>开头,最后以</SELECT>结束这个表单。SELECT标签一定要使用NAME参数来定义选项之栏位名称。
<br>
<br>
其参数如下∶
<br>
<br>
SIZE 当SIZE=1时,此表单为「卷动式表单」,大1时则是下拉式表单。若没有指定SIZE,则内定值为1。
<br>
MULTIPLE 当指定此参数时,不管有无指定SIZE参数,此表单一定是「卷动式表单」,并且允许文件阅读者从表单中一次选取一个以上的选项。
<br>
OPTION标签内可以加上参数SELECTED,表示此选项为内定值,已经预先被选择了。在一个MULTIPLE表单中可以有多个选项被设为内定值。
<br>
<br>
请参考下面的范例∶
<br>
<br>
<br>
--------------------------------------------------------------------------------
<br>
<br>
<H3><PAlign=Center>本公司产品介绍</P></H3>
<br>
<P>请选择一个项目以获得进一步说明∶</P>
<br>
<Form>
<br>
<SELECTNAME="Product"SIZE=8>
<br>
<OPTION>舒跑运动饮料
<br>
<OPTIONSELECTED>伯朗蓝山咖啡
<br>
<OPTION>开喜乌龙茶
<br>
<OPTION>雀巢柠檬茶
<br>
<OPTION>波蜜果菜汁
<br>
<OPTION>黑松沙士
<br>
<OPTION>统一优酪乳
<br>
<OPTION>可口可乐
<br>
<OPTION>义美果茶小站
<br>
</SELECT>
<br>
<P><INPUTTYPE=SUBMITVALUE="选择完毕"></P>
<br>
</Form>
<br>
<br>
结果如下∶
<br>
<br>
本公司产品介绍
<br>
<br>
请选择一个项目以获得进一步说明∶
<br>
<br>
舒跑运动饮料 伯朗蓝山咖啡 开喜乌龙茶 雀巢柠檬茶 波蜜果菜汁 黑松沙士 统一优酪乳 可口可乐 义美果茶小站
<br>
<br>
<br>
<br>
--------------------------------------------------------------------------------
<br>
<br>
3-2-4 TEXTAREA标签
<br>
<br>
使用格式如下∶
<br>
<br>
<TEXTAREA NAME=ValName ROWS=Number COLS=Number>
<br>
<br>
这文字输入区
<br>
<br>
这个标签的目的在提供一个多行的输入区域。以开始,以结束。这个标签也允许设定内定值,供使用者修改。输入区的大小由ROWS与COLS 这两个参数决定。例如∶ROWS=20 COLS=5表示一个大小为20乘5的输入区。
请参看下列范例∶
--------------------------------------------------------------------------------
请输入您对本公司的建议∶
我的建议是∶
结果如下∶
请输入您对本公司的建议∶
我 的 建 议 是 ∶ss
--------------------------------------------------------------------------------
当使用者输入的资料送到程序内时,程序会同时接收到NAME及VALUE的值。但当所使用的FORM中有RADIO或SELECT等多选择的资料输入型态时,程序则会接收到同一个N AME的值会对应到多个VALUE的值。程序可以藉著这样的特性,分辨使用者所做的多重选择并加以处理。但是,SELECT和RADIO的传回值并不相同。在R ADIO中,其值并不是FORM上所见到的值,而是在VALUE中所设定的值;在SELECT中,则是以OPTION标签之后的值为传回值。也就是说使用S ELECT,程序所收到的值和使用者看到的一样;使用RADIO则可以设定不同的值,使得使用者可以见到有意义的选项,而程序可以以更简单的参数,来处理使用者选择的资料。如果,在R ADIO中没有设定VALUE的值,则传回的是字串"on"。
四、CGI如何工作?
4-1 CGI工作流程
首先在客户端,客户端按下FORM上的SUBMIT按钮或是按下链结(LINK),告知浏览程序(Browser)完成输入后。浏览程序(Browser)将客户端输入的资讯传回W WW Server,Server启动指定的程序并将包装过的参数传入。接着程序依照传入的参数完成指定的工作。如果此时有需要传回结果的话,则程序会把结果传回给S erver,Server再传至浏览程序(Browser),完成整个工作的流程。下图是CGI工作流程的示意图∶
如果现在要让WWW Server与其它的系统结合,则程序会扮演中介的角色,将接收到的参数转换成所要结合系统能识别的形式,并处理其传回的资讯,再送回至S erver让使用者看到。下图是结合其它系统之后CGI工作流程的示意图∶
接下来这二张图是以MicroSoft SQL Server为例,结合WWW Server之后CGI工作流程的示意图∶
4-2 CGI 传递资料的方法
在CGI整个传递资料的过程中,为了要从 Server 传递有关输入资料给CGI程序,Server将不同的资料转换为各种环境变量以供CGI程序使用。这些环境变量是在Server执行CGI程序时被设定。我们在下一小节,将会介绍各环境变量,在这里我们将重点放在,C GI如何将使用者经FORM所输入的资料会被如何处理再送到CGI程序中。这是CGI的关键所在,有了这项资料才能正确的收到并处理使用者输入的资料。
在FORM中,每一资料输入栏中必须设定NAME之参数。当资料被送出时,NAME参数的值会和其相对应的VALUE参数之值,被转换为"NAME=VAL UE"的形式。不同的资料输入栏,中间会以"&"作分隔,亦即会形成"NAME1=VALUE1&NAME2=VALUE2"的形式。如果各参数值中间有空白的话会以" +"代替,有特殊字元则以"%XX"代替,其中"XX"为特殊字元的16进位ASCII码。这些特殊字元包括了"&"、"="、中文以及ASCII码为128以上的字符。
资料经过这样的包装后,如果METHOD是设定为POST的话,资料会以STDIN的方式送入CGI程序中;如果METHOD是设定为GET的话,资料会被送入Q UERY_STRING的环境变量中,以供程序读取。
在前面的小节曾说过,CGI的程序可以用链结的方式起动,此时资料须以上述的方法包装后,加在程序名称的后方,最前面要有一"?"符号与程序名称分隔。以下是一简单的范例∶
按这里
接着,我们分别就不同的传输METHOD做出的小范例,来比较不同的METHOD,在读取环境变量时有何不同∶
栏位#1:
栏位#2:
以上是以METHOD POST的方式传输资料,所应参考的环境变量如下∶
CONTENT_LENGTH=25
CONTENT_TYPE=application/x-www-form-urlencoded
REQUEST_METHOD=POST
SCRIPT_NAME=/CGI-BIN/TEST
上面环境变量中,较值得注意的是CONTENT_LENGTH,这个环境变量代表的是输入资料的长度,以供CGI程序参考。其计算的方式是以包装过后的实际长度为其值,所以上例的输入资料为" NAME1=AA+BB&NAME2=CC%3DDD",长度25个字元。
接下来,我们看看METHOD GET的范例∶
栏位#1:
栏位#2:
以上是以METHOD GET的方式传输资料,所应参考的环境变量如下∶
PATH_INFO=/CGI-BIN/TEST
PATH_TRANSLATED=/document_root/CGI-BIN/TEST
QUERY_STRING=NAME1=AA+BB&NAME2=CC%3DDDREQUEST_METHOD=GET
由上面的例子可以看出,不同资料的传输方式,所参考的环境变量并不一样。所以程序在发展时,要注意与输入介面上设定的传输方式一致,不同的程序不应该混用,以避免产生不必要的错误。
4-3 CGI的参数
这些环境变量仅供参考,并不见得会适用每一个WWW Server。所以,您在使用这些环境变量时,请先阅读过您的WWW Server手册,以免产生不必要的错误!
五、CGI的输出介面
资料输出是CGI流程的最后一部分,由送出的资料不只一种型态。为了使WWW Server能够辨认不同的资料型态,是在送出资料前,必须先送出特定的额外资讯以做为辨认的依据。
下面,将介绍额外信息的格式,以及在程序编写上,如何去完成输入和输出的工作!
5-1 CGI输出格式
当程序完成工作后,如果要输出资讯回馈给使用者,则程序必须将结果以资料流的方式传回给Server。Server负责把资料流以超本文传输协定( HTTP)的形式包装起来,并利用 HTTP1将资料流转换给客户端的浏览程序(Browser)。这表示,Server通常会将需要的超本文传输协定(HTTP)文件头(HEADER)加入CGI程序输出的结果中。
输出的资料流中包含两大部份。第一是简短文件头,用来告诉Server一些和程序执行结果有关的讯息。第二就是程序执行完的结果,Serv er并不会解译或更改这一部份的资料,也就是客户端的浏览程序(Browser)会完全接收到这一部份的资料。这两个部份之间要有一个以上的空白行作区隔。
程序执行完的结果是依您程序目的不同而有不同,而文件头却有几种固定的形式。当Server接到无法认定的文件头时会原封不动地送给客户端的浏览程序( Browser),所以CGI程序应避免送出不合超本文传输协定(HTTP)标准的文件头,以免发生错误的动作。
文件头跟MIME或MAIL的开头相似。它包含数行,每一行代表一个项目以及其参数,项目及参数以":"作区隔。以下是各文件头及其介绍∶
Content-type:type/subtype
告诉Server要输出的资料是属何种MIME型态的资料,type/subtype的值必须是MIME承认的型态之一。
举例来说,如果要输出的是超本文标示语言(HTML)文件则type/subtype应改为text/html。如果要输出的是JPEG标准的图形文件,则type/ subtype应改为image/jpeg。有关MIME的资料请自行参考相关资料。以下有一简单的范例以供参考∶
---开始---
Content-type:text/html <==内容的MIME type
Status:200OK <==超本文传输协定(HTTP)状态(非必要)
<==文件头和内容的分隔空白行
<==内容开始
范例文件
[...etc.]
---结束---
Status:
说明CGI执行的况状,其值必须是超本文传输协定(HTTP)所认可的。如果CGI程序传回的结果中,并未包含此一文件头的话,Server会认定C GI已成功的完成了工作,并且Server会自行产生"200OK"的Status值。关超本文传输协定(HTTP)Status值的设定,请自行参考相关资料。
URI:
在两个角括号中间的值可以是完整的URL,或是相对位址指向某一文件案,则这一文件案的内容将会取代CGI程序输出的结果。如果值是区域性的文件案,S erver会将文件案内容直接送到客户端。如果是完整的URL则Server传回"401redirect"的讯息,让浏览程序(Browser)自行抓取指定的文件案。
Locantion:
与URL同,但其后之值不必在角括号中间。以下是一简短范以供参考∶
---开始---
Location:http://jc.126.com <==指定之URL\
<==空白行
---结束---
如果CGI程序所送出的结果不希望经过Server的包装,而希望直接送到客户端的浏览程序(Browser),则程序必须负责送出完整的超本文传输协定( HTTP)信息包(Message Packaged)。当Server收到CGI程序输出的结果时,会先检查是否有"HTTP/1.0"的讯息。如果有则Server会认为以下的讯息已经包含了完整的超本文传输协定( HTTP)回应,并将其直接送至客户端的浏览程序(Browser)。以下是一简短的范例∶
---开始---
HTTP/1.0200OK <==超本文传输协定(HTTP)文件头开始
Date:Tuesday,31-May-9419:04:30GMT
Server:WebSite2.0
MIME-version:1.0
Content-type:text/html
Last-modified:Sunday,15-May-9402:12:32GMT
Content-length:4109 <==文件头和内容的分隔空白行
[...etc.]
---结束---
5-2 Perl 基本程序范例
在程序的编写上
第一步:要先读取环境变量REQUEST_METHOD的值,以分辨资料传输的方式。
第二步:依不同传输方式,接收使用输入资料━POST METHOD以STDIN的方式读入资料;GET METHOD 则从环境变量QUERY_STRING中读取客户端输入的资料。
第三步:将这个包装过的资料以反方向拆解开,分别置入不同的变量中。在处理过这些变量和完成所要的工作之后,输出资料回馈给使用者,是程序流程上的最后一个步骤。输出的资依上一小节所介绍的格式以S TDOUT的方式送出后,程序到此之后可以算是大功告成!
下面是CGI程序流程的简单示意图∶
--------------------------------------------------------------------------------
由于Perl的程序由处理文件时较C语言简洁且为直译式语言,所以在CGI中有极为广泛的应用。范例程序主要的目的是接收并且输出资料。接着我们就开始逐步介绍程序中的重点部分。首先我们看的是利用S TDOUT输出文件头,告知Server何种内容将会送出∶
print "Content-type:text/html\n\n";
从上面的程序可看出,程序接着要输出的内容将会是超本文标示语言(HTML)的文件。事实上,文件头的输并不一定要放在程序的开头处,但一定要在内容输出前,这点请特别注意。而且,在看看这一行程序的最后有两个" \n"符号,为的是要再加上一行空白,以便和接着输出的内容做区隔!输出文件头之后是辨认传输的方式以及读入使用者输入的资料∶
if($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
}elsif($ENV{'REQUEST_METHOD'} eq "GET")
{ $buffer = $ENV{'QUERY_STRING'};
}
可由上方的程序看出,不同的METHOD读取使用者输入资料的方式并不相同,请勿混用!
完成了资料读取之后,接下来则是重头戏━分解资料。
@pairs=split(/&/,$buffer);
foreach $pair (@pairs)
{
($name,$value)=split(/=/,$pair);
$value=~tr/+//;
$value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
$A{$name}=$value;
print "
$name=$value\n\n";
}
事实上,本范例并未将不同的资料置入不同的变量中,而是直接输出。如果您想要对资料做进一步的处理,可以将程序加以修改、扩充。请注意,在输出变量之前已先输出部分的超本文标示语言( HTML)文件的内容。
print "
查询结果
";
print "您输入的查询值如下∶
\n";
print "
\n";
由上可见,用程序输出超本文标示语言(HTML)文件和一般建立超本文标示语言(HTML)的格式并无差异,不同的只是建立者是人与程序的分别!
以下是完整的程序列表∶
--------------------------------------------------------------------------------
#!/usr/local/bin/perl
$|=1;
print "Content-type:text/html\n\n";
if($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
}elsif($ENV{'REQUEST_METHOD'} eq "GET")
{ $buffer=$ENV{'QUERY_STRING'};
}
print "
查询结果
";
print "您输入的查询值如下∶
\n";
print "
\n";
@pairs=split(/&/,$buffer);
foreach $pair (@pairs)
{
($name,$value)=split(/=/,$pair);
$value=~tr/+//;
$value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
$A{$name}=$value;
print "
$name=$value\n\n";
}
print "
\n"
--------------------------------------------------------------------------------
上面的程序是一个「麻雀虽小,五脏俱全」的程序。只要将其适当的位置加上所需的程序就可以达到预定的功能,相信能对您有所助益。