CGI教程.docx

上传人:b****5 文档编号:4575358 上传时间:2022-12-06 格式:DOCX 页数:27 大小:34.52KB
下载 相关 举报
CGI教程.docx_第1页
第1页 / 共27页
CGI教程.docx_第2页
第2页 / 共27页
CGI教程.docx_第3页
第3页 / 共27页
CGI教程.docx_第4页
第4页 / 共27页
CGI教程.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

CGI教程.docx

《CGI教程.docx》由会员分享,可在线阅读,更多相关《CGI教程.docx(27页珍藏版)》请在冰豆网上搜索。

CGI教程.docx

CGI教程

CGI教程

(1)

CGI是一个连接外部应用程序到信息服务器(比如HTTP或者网络服务器)的标准。

一个简单的HTML文档是无交互后台程序,它是静态的,也就是说它处于一个不可变的状态,即文本文件不可以变化。

相反地,CGI程序是可以实时执行地,它可以输出动态的信息。

举个例子吧,如果你想把Unix数据库”挂到”万维网上,并允许世界各地的人可以访问它。

基本上,就就需要创建一个CGI程序,它的执行将传递信息给数据库引擎,并且把解雇返回给用户显示出来。

这是一个网关的例子。

数据库例子是一个简单的思想,在实际应用过程中更为复杂。

实际上没有什么不能挂到网络上面的。

但是只有一件事情你必须记住:

不管你的CGI程序是怎样,一定不能花太多的时间来处理。

否则,用户就做在奔腾机前面静静地等着浏览器的显示结果,这势必伤透了”奔腾的心”。

下面讲讲CGI的特殊要求:

既然CGI程序是可执行的,那基本上就等价于世界任何地方的人可以在你的系统中运行CGI程序,所以这是一种不安全的事情。

因此在使用CGI程序的时候,需要一些安全的预防措施。

可能,一种有效的方法是将CGI程序放置在一个特殊的目录中,这样网络服务器件只是执行CGI程序而不是将它显示到浏览器中。

这个特殊的目录通常处在网络管理员直接控制的目录,这样就可以阻止普通用户创建CGI程序。

仍然有其它几种方法可以允许用户访问CGI脚本,但是这需要网络管理员为他进行一些设置。

在这一点上,你可能有与网络管理员联系以获得访问CGI权限的冲动。

如果你有一个NCSAHTTPd服务器分布的版本,你将看到一个目录/cgi-bin。

这个目录就是上面所提的特殊目录,它就是放置CGI程序的地方。

CGI程序可以用任何的语言来编写,并且可以在以下的系统中执行:

C/C++

Fortran

PERL

TCL

任何的Unixshell

VisualBasic

AppleScript

采取什么的语言依靠你的系统支持什么语言而定的。

如果你使用过一个编程语言如C或者Fortran,你就会知道在运行程序之前必须对程序进行编译。

如果你进入这个目录,你就会发现一些CGI程序的源代码。

但是如果你使用其中一种脚本语言,比如PERL、TCL或者Unixshell,脚本就只需要放置在/cgi-bin目录中,因为没有相关的源代码。

许多设计人员喜欢使用CGI脚本而不使用编程语言,因为脚本比需要编译的程序语言更容易调试、修改和维护。

CGI教程

(2)

怎样从服务器获得信息

  每次客户端需要URL来对应CGI程序,服务器将实时执行它。

程序将直接输出到客户端。

关于CGI的公用的误解是你可以发送命令行选项和参数给你的程序,比如:

command%myprog-qablorf

  CGI为其它目的使用命令行,这样是不可能。

相反,CGI使用环境变量来发送给程序它的参数。

两个重要的环境参数是:

QUERY_STRING和PATH_INFO。

  QUERY_STRING被定义为在URL中跟在第一个?

后面的内容。

这个信息可以由ISINDEX文档或者通过HTML表单(利用GETaction)来增加。

它同样可以手动嵌入HTML锚,这个HTML锚可以引用你的网关。

这个字符串就是一个信息查询,比如用户想搜索archie数据库或者是你的反馈GET表单的编码结果。

  这个字符串被在标准的URL编码,其格式将空格转换为+,并将特殊的字符利用%xx十六进制编码。

你为了使用它必须对它进行编码。

  如果你的网关不是从表单来的编码结果,你同样可以利用命令行得到查询字符串。

这就意味着查询字符串的每一个单词将在ARGV的不同部分。

比如,查询字符串"formsrule"将以argv[1]="forms"和argv[2]="rule"传递给程序。

如果你选择这个,你在使用它之前不必做任何的处理。

  下面讲讲PATH_INFO。

CGI允许为你的网关在URL中嵌入额外的信息,这个网关可以用于传递额外的信息给脚本。

这个信息通常是处在URL的网关路径之后的额外信息。

这个信息不能在服务器中以任何的方法来编码。

  最亦用的PATH_INFO例子是传递文件位置给CGI程序。

为了阐述这个,假设我们有一个CGI程序在服务器中,名为/cgi-bin/foobar,它可以处理在服务器的DocumentRoot中的文件。

这时我需要通知foobar哪个文件要被处理。

通过包括额外的路径信息到URL的末尾,foobar通过PATH_INFO环境变量就知道了文档位置相关的DocumentRoot,或者通过PATHTRANSLATED环境变量(服务器为你产生的)来知道文档的真实路径。

CGI教程(3)

怎样发回文档给客户端

对于CGI的初学者,一个公共的错误是没有正确格式化输出,这样服务器不能解释它。

CGI程序可以返回各种文件类型。

它们可以返回给客户端一张图片、HTML文档、明文文档或者可能是一个音频夹。

它们同样可能返回其它文档给引用。

客户端必须知道哪种类型的文档你要发送,这样它就可以相应地将它显示出来。

为了让客户端知道这个,CGI程序必须通知服务器哪种类型的文档将被返回。

为了通知服务器哪种类型的文档你想送回,而不管这个文档是一个完整的文档或者一个引用,CGI要求你放置一个短的数据头到输出中。

这个数据头是一个ASCII文本,它包含了被linefeeds或者carriage返回的行,其后还跟着一个空白行。

在本例子中,你必须通过一个MIME类型通知服务器什么类型的文档你要输出。

公共的MIME类型是一些比如html/text以及ASCII文本。

比如,为了返回HTML给客户端,你的输出代码为:

Content-type:

text/html

outputofHTMLfromCGIscript

Sampleoutput

Whatdoyouthinkofthis?

如果不输出文档,你可以只通知浏览器哪儿可以得到这个新文档或者让服务器自动为你输出新的文档。

比如,假如你想从Gopher服务器中引用一个文件。

折中情况,你应该知道你想引用和输出的完整的URL,代码如下:

Content-type:

text/html

Location:

gopher:

//httprules.foobar.org/0

 

 

Sorry...itmoved

 

 

Gotogopherinstead

 

Nowavailableat

 

//httprules.foobar.org/0">anewlocation

 

onourgopherserver.

 

但是,现在的浏览器很是聪明,它会自动将新文档显示给你而不会看到上面的内容。

如果不想输出上面的HTML,NCSAHTTPd会为你输出一个缺省的文档来支持旧的浏览器。

如果你想引用你自己服务器上另外文件(没有受到返回验证的保护),你不必做太多的工作,而只需要输出一个不完全的URL,代码如下:

Location:

/dir1/dir2/myfile.html

这时服务器就会认为客户端没有请求你的脚本,而是请求http:

//yourserver/dir1/dir2/myfile.html。

你要注意文件类型以及数据头对不对。

如果你想引用一个受到访问验证保护的文档,你就不得不键如完整的URL,因为客户端和服务器需要重新处理来建立你访问引用文档的连接。

HTML表单

FORM(表单)标签

表单的标签在HTML文档中指定了一个表单。

在一个文档中可以有多个表单,但是一点必须注意表单不能嵌套。

... 

具体属性如下:

ACTION是将要提交的表单中查询服务器的URL,如果这个属性是空的,那么当前的文档URL将被使用。

METHOD是HTTP/1.0方法,它使用与提交表单给查询数据库。

你使用哪个方法取决于你特定的服务器是怎么工作的。

这里强烈推荐使用POST。

当然你也可以使用GET。

POST和GET具体描述如下:

GET—这是一个缺省的方法,它将表单内容附加给URL,就好象它们是普通查询。

POST--–这个方法是将表单内容作为一个数据体而不是URL的一部分传送给服务器的。

ENCTYPE为表单内容指定编码。

这个属性只有在METHOD被设置为POST的时候才应用,并且只有一种可能数值(缺省值为application/x-www-form-urlencoded)。

在表单中,你除了不能表单外,你可以使用INPUT(输入)、SELECT(选择框)以及TEXTAREA(文本域)。

因为表单不会自动从文档的其余部分中区分开来。

我们推荐在一个表单之前使用HR(horizontalrule,水平线)标签来区分。

CGI教程(5)

INPUT(输入)标签

输入标签用于在表单中指定一个简单的输入元素。

它是一个独立的标签,它旁边没有其它内容并且没有终止标签,它跟IMG的用法是一样的。

输入标签具体的属性为:

TYPE(类型)必须为以下的一种:

"text"(文本),这个是缺省的。

"password"(密码),看不到键入的字符,只有星号。

 

"checkbox"(复选框),是一个单一的切换按钮,有开和关两种状态。

 

"radio"(无线电按钮),单一的切换按钮,有开和关两种状态,可以组成一个组,用于多选一的操作。

 

"submit"(提交),它是一个按钮,将当前的表单包装到查询URL中并且将它发送到远程的服务器中。

 

"reset"(复位),也是一个按钮,它可以使表单中的各种输入复位到它的缺省数值。

 

NAME是为输入区域的一个符号名字(不是显示的名字---表单中HTML通常使用的)。

VALUE是文本或者密码区域,它可以用于指定缺省区域内容。

对于一个复选框或者一个无线电按钮,VALUE指定当它被选择的时候按钮的值。

复选框或者无线电按钮的缺省值为”on”。

对于"submit"(提交)and"reset"(重置),VALUE可以为按钮用于指定标志。

 

CHECKED(不需要数值)指定复选框或者无线电按钮被选中。

它只适用于复选框或者无线电按钮。

 

SIZE使指定输入区域字符串的大小,它只对文本区域和密码输入区域有效。

如果这个没给出,缺省的设置为20。

多行的文本输入区域可以指定为SIZE=width,height;比如SIZE=60,12。

这里注意:

SIZE属性不应该要来指定多行文本输入区域因为TEXTAREA标签是有效的。

 

MAXLENGTH是可以接受的字符串的最大数目,它只适用于文本区域和密码区域。

如果它没有设置则缺省的值是无穷大。

如果MAXLENGTH大于SIZE则文本区域就可以滚动。

 

CGI教程(6)

SELECT(选择框)标签

...
里面有多少个SELECT标签都是允许的,它可以混合其它HTML元素(包括INPUT和TEXTAREA元素)和文本,但是不能包括FORMS。

.不象INPUT,SELECT有和关闭标签。

在SELECT里面,只有一系列的OPTION标签,每一个OPTION标签之后跟着一些文本,比如:

 

SELECT的属性有:

NAME是为这个SELECT元素起的名字。

它不能为空,必须给出具体值。

SIZE:

如果SIZE是1或者如果SIZE的属性没有,SELECT缺省为一个Motifoption菜单。

如果SIZE为2或者更大,SELECT将作为一个Motif出现滚动的列表。

这个SIZE的数值决定了列表中有几项。

 

MULTIPLE:

如果出现(它没有数值),它指定选择框可以进行多行选择。

 

OPTION的属性如下:

 

SELECTED指定缺省状态这个OPTION被选择。

如果SELECT允许多行选择,多个OPTION可以指定为SELECTED。

CGI教程(7)

TEXTAREA(文本域)标签

TEXTAREA标签被用来放置一个多行的文本输入区域。

它有以下的属性:

NAME是文本域的名字。

 

ROWS是文本域的行数。

 

COLS是文本域的列数(即字符的水平宽度)。

 

TEXTAREA域自动有滚动条。

不论多少的文本都可以件入到里面。

 

TEXTAREA元素需要一个打开和关闭的标签即

没有缺省内容的TEXTREA如下所示:

 

 

有缺省内容的TEXTREA如下所示:

 

Defaultcontentsgohere. 

 

缺省内容必须是ASCII文本。

 

CGI教程(8)

表单的提交

下面先讲讲Method=GET:

当提交按钮被按下,表单的内容将被汇编到查询URL中,如下所示:

action?

name=value&name=value&name=value 

"action"由FORM标签设置的ACTION指定的URL,或者如果没有ACTION属性没有被指定的时候,是当前的文档URL。

在"name"或者"value"任何实例中奇怪的字符都将被视为正常的字符,当然包括"="和"&"等等。

这里注意,"="是分离名字和数值,而"&"示分离名字/数值对的。

对于文本和密码域,不管用户键入什么都将视为数值。

如果用户没有键入任何的内容,这个数值将是空,但是"name="还是会出现。

对于复选框和无线电按钮,VALUE属性指定了复选框或者无线电按钮被选中的时候的值。

一个未选中的复选框会在汇编查询字符串的时候被忽视。

多个复选框可以有相同的名字(和不同的数值)。

多个无线电按钮是用于多选一的情况,它可以有相同的名字但是不同的数值。

再来谈谈Method=POST吧:

表单的内容跟上面讲述的GET方法的编码是一样的,但是不是将它们附加到URL由于表单ACTION属性指定为查询,而是这些内容将作为POST操作的一部分以数据块发送的。

这个ACTION属性是数据块要POST的URL。

测试服务器

如果你想编写原型的表单并对它在查询服务器上进行测试,你可以编写如下代码:

对于METHOD="POST",使用ACTION="http:

//hoohoo.ncsa.uiuc.edu/cgi-bin/post-query" 

对于METHOD="GET",使用ACTION="http:

//hoohoo.ncsa.uiuc.edu/cgi-bin/query" 

CGI教学:

第一章cgilib例

一个简单的读取并处理表格请求数据的cgilib.pl例子:

#!

/usr/bin/perl

subreadGetData{ 

#指定局部变量queryString用以保存和传递函数的参数 

local(*queryString)=@_if@_; 

#读取环境变量QUERY_STRING的值赋给变量$queryString 

$queryString=$ENV{"QUERY_STRING"}; 

return1;

}

subreadPostData{ 

local(*queryString)=@_if@_; 

local($contentLength); 

#读取环境变量CONTENT_LENGTH的值 

$contentLength=$ENV{"CONTENT_LENGTH"}; 

#检查是否有数据 

if($contentLength){ 

#从设备STDIN读取contentLength长度的字符赋给$queryString 

read(STDIN,$queryString,$contentLength); 

return1; 

subreadData{ 

local(*queryString)=@_if@_; 

#读取环境变量REQUEST_METHOD 

$requestType=$ENV{"REQUEST_METHOD"}; 

#如果请求方式为GET则使用函数readGetData 

#否则如果请求方式为POST则使用函数readPostData 

if($requestTypeeq"GET"){ 

&readGetData(*queryString); 

elsif($requestTypeeq"POST"){ 

&readPostData(*queryString); 

return1; 

subDecodeData{ 

local(*queryString)=@_; 

#把加号转换成空格 

$queryString=~s/\+//g; 

#转换十六进制字符 

$queryString=~s/%(..)/pack("c",hex($1))/ge; 

return1; 

subparseData{ 

local(*queryString,*formData)=@_if@_; 

local($key,$value,$curString,@tmpArray); 

#以&为分隔符把字符串转换成键-值对 

@tmpArray=split(/&/,$queryString); 

#在数组@tmpArray内循环 

foreach$curString(@tmpArray){ 

#以=为分隔符分开键-值对 

($key,$value)=split(/=/,$curString); 

#解码 

&DecodeData(*key); 

&DecodeData(*value); 

#把键和值加到字典中 

$formData{$key}=$value; 

return1; 

1;

#endoffilecgilib.pl 

使用方法:

要使用此库需含下列语句:

#require"cgilib.pl";

表格数据处理:

%dataDict=();

&readData(*data);

&parseData(*data,dataDict);

字典数据处理:

 

while(($key,$value)=each(%dataDict)){ 

print$key,"=",$value,"\n\n";

}

CGI教学:

第二章动态创建图像

“动态文档”不仅指文本,CGI程序可以创建图象、声音等各种媒体。

你只须输出相应的MIME头、一行空行及原始数据即可。

下例的image.cgi将装载一个GIF图像文件并送到浏览器显示:

 

#!

/usr/bin/perl

$file='/usr/local/etc/httpd/htdocs/images/picture.gif';

print"Content-Type:

image/gif\n\n";

open(GIF,"<$file")||die"Can'topenGIF\n"; 

while(read(GIF,$buffer,16384)){

print$buffer;

image.cgi首先发送MIME头说明(Content-Type),然后读取文件内容并输出。

这段程序对$file变量和Content-Type类型略加修改就可以发送声音或影像文件。

那么怎样把CGI程序创建的图像嵌到页面中呢?

SSI是不行的,方法是用标签,语法如:

仅就显示picture.gif这幅图像而言,用上述的image.cgi是没有什么意义的,更恰当的方式是这样使用:

但是,image.cgi可以扩展功能来做更多的事。

例如它可以从多个图像文件中随即地选择一个来显示,那么,每一次访问该页面时都会出现不同的图像。

计数器程序通常利用标签的这一特性,尤其是那些不允许解析HTML和SSI的服务器特别实用。

服务器端不解析HTML文件可以降低服务器的负载。

此外,除了简单的装载并显示已有的图像文件外,可以真正的动态生成所需的图像。

你可以设计一个CGI程序根据不同的参数及用户定义的一些细节来实时创建相应的图像(如图表)并显示。

这种程序的复杂性在于图像的生成而不在于将图像输出给浏览器。

幸运的是,有一些库提供了这样的接口,如Thomasboutell的gd图像库,这是生成GIF图像的一个出色工具,可以从

下面是一个简单的用位图动态生成图像的计数器程序,对理解上述描述应该会有所帮助。

(源代码下载)

您是第位访问本网页的人。

附:

GIF的说明

现在流行着一种趋势,即远离GIF格式而采用PortableNetworkGraphic格式(PNG),这种变化出于技术和法律两个方面的考虑。

1995年1月1日,Unisys声称他们有权要求使用LZW压缩算法的软件公司要经过他们的许可或付给他们报酬,因为他们拥有专利使用权。

而GIF格式正是使用这种算法。

所以,你所编写的任何用于商业应用程序中的GIF图像(包括以CGI/WWW为基础的那些文件),都必须购买许可证或支付费用。

许多软件包不再压缩GIF文件(这样会使图像变得很大),或者把GIF文件及其支持软件全部去掉。

PNG使用非专利的压缩算法,从而避免了这些麻烦。

在技术方面,PNG提供了较好的压缩算法(无损失,像GIF一样,但不像JPEG。

JPEG在压缩时会丢失数据)、二维交互以及24位和48位真彩支持。

现在,很少有浏览器支持内插的PNG图像,但不久的将来,这种情况很可能会改变。

GD图形库文件说明了PNG支持即将来临。

CGI教学:

第三章计数器的编写方法

一、记录(log)文件

1、grep

2、page-stats

3、wusage

二、创建自己的计数器

1、使用DBM文件

2、文本文件

3、文件锁定

4、输出计数结果

5、wwwHomepageAccessCounter

6、使用GD图形库

计数器(AccessCounter)可以记录网页被访问的次数,在万维网上的使用十分普遍,其

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1