三、 CGI设计进阶

三、 CGI设计进阶

1. 处理表单的CGI程序
    表单允许用户输入各种信息,而通常CGI程序和带参数的CGI程序不能处理客户的输入或只能处理带硬编码参数的程序。因此出现了专门处理表单的程序。处理表单的CGI程序的编写须注意那些与表单有关的因素。
    编写一般步骤为:
    ⑴由于表单传给CGI程序的数据是经URL编码的,因而编写前需调用cgiparse、uncgi或cgi-lib.pl程序对输入进行解码。
    ⑵输出标准数据类型标题,地址类型标题或状态类型标题,这些标题后要以两个\n(换行)字符结尾。第一个\n表示换行,第二个\n表示标题后面的空行。
    ⑶输出对应版面开头部分的HTML程序。
    URL编码就是由浏览器把通过表单输入的数据──变量/变量值转化为参数/参数值,同时把那些不能直接传输的符号,如:&,%,+转化为16进制。
    编码规则:
    参数/参数值对之间用“&”分隔,空格用“+”代替
    参数与参数值之间用“=”分隔,如果参数未赋值,参数也同样出现在编码中,如:“姓名=”。
    一些特殊符号:&,%,+转化为带%的16进制数:%NN。
    例:URL编码:姓名: 张三 & 性别: 男 & 民族:汉
    可以根据编码规则和环境变量,自己编写解码程序,也可直接使用现成的解码程序。
    ⑴使用解码程序cgiparse制作CGI:
    cgiparse:这是处理GET方式和POST方式的很有用的程序,是CERN格式服务器程序的一部分,如果服务器为其它格式,请选用其它解码程序。
    使用CGIPARSE程序时,需根据不同的表单式输入采取相应的参数在CGI程序的开头调用CGIPARSE程序。若使用GET命令发送表单输入,则cgiparse程序使用form选项将参数名/参数值对进行解码并存入与变量同名的Shell环境
变量中,只是在名字前面加上form_前缀,即若变量原来为mybook, cgiparse产生的环境变量为FORM_mybook。
    在Bourne shell中程序调用cgiparse处理GET输入格式为eval/home/www/cgi-bin/cgiparse-form
    若使用POST命令地送表单输入,可以有几种途径处理输入。其中最简单的方法是,使用_init选项,从标准输入读入输入量,并把它存入环境变量 QUERY_STRING中,然后选择_form选项调用cgiparse对参数名/参数值对进行解码,并存入环境变量中。
    因此在Shell程序中调用cgiparse处理POST输入需两行命令:
    eval/home/www/cgi-bin/cgiparse-init
    eval/home/www/cgi-bin/cgiparse-form
    例:#!/bin/sh
      eval/home/www/cgi-bin/cgiparse-init --- 第一部分:
      |--码,采用eval/home/www/cgi-bin/cgiparse-form --- cgiparse的POST方式
      echo"Conetnt-type:text/html" --- 程序第二部分:
      |-- 数据头,echo --- 数据类型为文本格式html文档
      注意应有一空行
echo"<HTML><HEAD>" --------
echo"<TITLE>Sleepometer Results |
</TITLE>" |
echo"<H3>Results:</H3> |
if [!-z "$FORM_the Name"]; 程序主体部分:
then echo"<P>$FORM_the Name is" 处理表单输入
else echo"<P>A Person with no name is" 注意输入数据fi 的格式
if["$FORM_sheepy"="yes"]; |
then echo"sleepy" |
else echo"Not sleepy" |
fi echo"</BODY></HTML> --------
    ⑵使用uncgi解码程序设计CGI程序
    uncgi:用C语言写成,处理方式与cgiparse类似,但比cgiparse易得到并能更好地处理POST方式的输入,可从:http://www.hyperion.eom/vkereth/uncgi.html/得到有关信息
    uncgi最好安装在目录cgi-bin中,编译前应修改Makefile文件,使其中的目录路径和你使用的系统一致。
    uncgi程序从用GET或POST方式输入数据中的表单中读入输入并解码,然后产生一组变量,这些变量都加上了www_前缀,如:原来的特征变量为 the work和playing,现在则对应为 www_the work和www_playing。
    对于多个参数名/参数值对使用相同名字时,只产生一个环境变量,每个变量值用#符号分开,如:参数名/参数值对为playing=baskeball, playing=baseball,则环境变量FORM_PLAYING的值为baskeball#baseball。
    使用uncgi程序时,需对FORM标注中的ACTION特征量作一点修改,不能在ACT\ON中直接调用,必须附上程序名,如:<FORM METHOD=POST ACTION="cgi-bin/kk.cgi">需改为<FORM METHOD=POST ACTION="cgi-bin/uncgi/kk.cgi">
例:#!/bin/sh 
    |--cgi程序的数据头部分:echo"Content=type:text/html" --- 使用uncgi 解码程序时,echo --- 不需要解
码部分,调用cgi时,自动调用uncgi进行解码
echo"<HTML><HEAD>" ---------
echo"<TITLE>Sleeppometer Results |
</TITLE>" |
echo"</HEAD><BODY>" |
echo"<H3>Results:</H3>" |
if [!-z"$www_the Name"]; cgi程序主体部分: 其中对两个表单变量进行了处理
then echo"<P>$www_the Name is" 
else echo"<P>A person with no the Name和sleepy name is"
fi | 
if ["$www_sleepu"="yes"]; |
then echo"sleepy." |
else echo"Not sleepy." |
fi |
echo"</BODY></HTML>" ---------
    ⑶使用cgi-lib.pl解码设计CGI程序
    cgi-lib.pl用perl语言编写,它从GET或POST读入表格是输入并存放在数组中。可从http://www.bio.cam.ac.uk/web/fom.html/得到有关信息
    cgi-lib.pl软件包,是由Steve Brener用perl编写的,它可以从用GET或POST方式输入的表单中读入表单式输入,并存放在一个perl表或相应的数组中,用户可以从地址 http://www.bio.cam.ac.uk/web/form.html/得到源程序和相应的资料
    用户若要使用cgi-lib,则可以从上述URL中取出源程序,并把它放在用户的perl目录中,且在用户程序中用命令veguire'cgi-lib.pl'把库目录中的程序包含进程序中。
    cgi-lib.pl包含好几个管理表单的程序,Read Parse是cgi-lib.pl软件包中最重要的一个表单管理软件。它能从用GET或POST输入的表单中读入输入值,并把输入值以参数名/参数值对的形式放入相应的perl数组中。
    Read Parse命令的调用格式为:& Read Parse(*数组名) 
    对于多个参数名/参数值使用相同的名字时,cgi-lib.pl会将数组中的值用\0空字符)分开。
例:#!/user/local/bin/perl
    cgi程序的第一部分:require‘cgi-lib.pl; --- 调用cgi-lib.pl软件包|---中的Read Parse&lead Parse(*in); --- 程序进行解码,结果放在数组in中
cgi程序的数据头部分:
print"Content_type:text/html\n\n"; ---说明数据是文本格式的html文档’
“\n\n”表示打印一个空行
 
print“<HTML><HEAD>”; --------
print“<TITLE>Sleeppometer Results |
</TITLE>” ; |
print“</HEAD><BODY>”; |cgi程序的主体部分:注意对表单输入变量的处理,
print“<H3>Results:</H3>”; 
if [$in{‘the Name’}]  
[ print“<P>$in{the Name}is”;] 
else{print“<P>A Person with no 
name is”;} 变量存放在数
if [$in{‘sleepy’}eq yes] 组in中 
{print“sleepy.”} |
else{print“not sleepy.”;} |
print“</BODY></HTML>”; -------
    使CGI程序通用化是非常重要的,从前面检查登录CGI的程序可知,若要检查不同人的登录情况,则需编写同样的CGI程序,但对于同样的情况,只需编写一个带参娄的CGI程序,如:只需将示例程序中的Ison:‘who I grep约翰’语句改为
    ison:‘who I grep“$第几个变量”’
即可。
    把参数赋给CGI程序,用如下方法连接:
    <A HERF=“cgi-bin/myscript?arg1+arg2+arg3>”
    clink hear.</A>
连接中问号后的arg1.arg2.arg3为将传给cgi-bin/myscript的参数,它们用“+”分开。
    下面举一个检查珍妮是否登录的例子:
#!/bin/sh
echo“Covtent_type:text/html”
echo
echo“<HTML><HEAD>”
echo“<TITLE>你登录了吗?</TITLE>”
echo“</HEAD><BODY>”
ison=“who I grep‘$2’”
if[-z“$ ison”];
the echo“<P>珍妮已登录。”
else echo“<P>珍妮未登录。”
fi
echo“</BODY></HTML>”
用户只需通过
    <A HREF=“上述程序的URL地址?约翰+珍妮”>
    珍妮登录了吗?</A>
即可在浏览器中显示珍妮是否登录的界面。

5. NPH(无处理头)程序
    NPH(non-processed headers)程序即非解释文件头程序,是为了加快服务器往浏览器传文件的速度,编写这种程序须按照以下格式:
    ⑴程序中需有一个nph前缀,如nph_pinglanra.
    ⑵程序除了原有的数据类型头、地址头及状态头外,还需加入HTTPD头。HTTPD头分为两部分:
    ① HTTP/1.0加上状态码,如:HTTP/1.0 2000k状态码200表示“一切正常,数据已送走。”
    ② 服务器头,它能显示出运行的服务器的版本号,如:Server: NCSA/1.3或Server: CERN/3.0 PRE6