相关模块 | 相关指令 |
---|---|
CGI(公共网关接口[Common Gateway Interface])定义了网站服务器与外部内容协商程序之间交互的方法,一般是指CGI程序或者CGI脚本,是在网站上实现动态页面的最简单而经常使用的方法。本文将对如何在Apache网站服务器上创建CGI以及如何编写CGI程序做介绍。html
要让CGI程序能正常运做,必须配置Apache以容许CGI的执行,其方法有多种。程序员
ScriptAlias
指令使Apache容许执行一个特定目录中的CGI程序。当客户端请求此特定目录中的资源时,Apache假定其中文件都是CGI程序并试图运行。web
ScriptAlias
指令形如:shell
ScriptAlias /cgi-bin/ /usr/local/apache/cgi-bin/
apache
若是Apache被安装到默认的位置,默认的配置文件httpd.conf
中则会有上述配置。ScriptAlias
指令定义了映射到一个特定目录的URL前缀,与Alias
指令很是类似,二者通常都用于指定位于DocumentRoot
目录之外的目录,其区别是ScriptAlias
又多了一层含义,即其URL前缀中任何文件都被视为CGI程序。因此,上述例子会指示Apache,/cgi-bin/
应该指向/usr/local/apache/cgi-bin/
目录,且视之为CGI程序。编程
举例,若是有URL为http://www.example.com/cgi-bin/test.pl
的请求,Apache会试图执行/usr/local/apache/cgi-bin/test.pl
文件并返回其输出。固然,这个文件必须存在并且可执行,并以特定的方法产生输出,不然Apache返回一个出错消息。浏览器
因为安全缘由,CGI程序一般被限制在ScriptAlias
指定的目录中,如此,管理员就能够严格地控制谁可使用CGI程序。可是,若是采起了恰当的安全方法措施,则没有理由不容许其余目录中的CGI程序运行。好比,你可能但愿用户在UserDir
指定的宿主目录中存放页面,而他们有本身的CGI程序,但无权存取cgi-bin
目录,这样,就产生了运行其余目录中CGI程序的需求。安全
能够在主服务器配置文件中,使用Options
指令显式地容许特定目录中CGI的执行:服务器
<Directory /usr/local/apache/htdocs/somedir>
网络
Options +ExecCGI
</Directory>
上述指令使Apache容许CGI文件的执行。另外,还必须告诉服务器哪些文件是CGI文件。下面的AddHandler
指令告诉服务器全部带有cgi
或pl
后缀的文件是CGI程序:
AddHandler cgi-script cgi pl
.htaccess
文件是针对目录进行配置的一种方法。Apache在提供一个资源时,会在此资源所在目录中寻找.htaccess
文件,若是有,则使其中的指令生效。AllowOverride
指令决定了.htaccess
文件是否有效,它指定了哪些指令能够出如今其中,或者根本不容许使用。为此,须要在主服务器配置中如此配置:
AllowOverride Options
在.htaccess
文件中,须要如此配置:
Options +ExecCGI
以使Apache容许此目录中CGI程序的执行。
编写CGI程序和``常规''程序之间有两个主要的不一样。
首先,在CGI程序的全部输出前面必须有一个MIME类型的头,即HTTP头,对浏览器指明所接收内容的类型,大多数状况下,形如:
Content-type: text/html
其次,输出要求是HTML形式的,或者是浏览器能够显示的其余某种形式。多数状况下,输出是HTML形式的,但偶然也会编写CGI程序以输出一个gif图片或者其余非HTML的内容。
除了这两点,编写CGI程序和编写其余程序大体相同。
这个CGI程序例子在浏览器中打印一行文字。把下列存为first.pl
文件,并放在你的cgi-bin
目录中。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, World.";
即便不熟悉Perl语言,你也应该能看出它干了什么。第一行,告诉Apache这个文件能够用/usr/bin/perl
(或者任何你正在使用的shell)解释并执行。第二行,打印上述要求的内容类型说明,并带有两个换行,在头后面留出空行,以示HTTP头的结束。第三行,打印文字``Hello, World.''。程序到此结束。
打开你喜欢的浏览器并输入地址:
http://www.example.com/cgi-bin/first.pl
或者是你存放程序的其余位置,就能够在浏览器窗口中看到一行Hello, World.
。虽然并不怎么激动人心,可是一旦这个程序能正常运做,那么就可能运做其余任何程序。
从网络访问CGI程序,浏览器中可能会发生四种状况:
记住,服务器不是以你的用户身份运行的,就是说,在服务器启动后,拥有的是一个非特权用户的权限-一般是``nobody''或者``www'' -而须要更大的权限以容许文件的执行。一般,给予``nobody''足够的权限以执行文件的方法是,对文件赋予everyone execute权限:
chmod a+x first.pl
另外,若是须要对其余文件进行读取或写入,也必须对这些文件赋予正确的权限。
若是服务器被配置为使用suexec则是一个例外。这个程序容许CGI程序根据其所在虚拟主机或用户宿主目录的不一样而以不一样的用户权限运行。Suexec有极其严格的权限校验,任何校验失败都会使CGI程序运行失败而产生"Internal Server Error"。对此,须要检查suexec的日志文件以发现哪一个安全校验出问题了。
当你在命令行执行一个程序,某些信息会自动传给shell而无须你操心,好比一个路径,告诉shell你所引用的文件能够在哪儿找到。
可是,在CGI程序经过网站服务器执行时,则没有此路径,因此,你在CGI程序中引用的任何程序(如sendmail)都必须指定其完整的路径,使shell能找到它们以执行你的CGI程序。
一种普通的用法是,在CGI程序的第一行中指明解释器(一般是perl
),形如:
#!/usr/bin/perl
必须保证它的确指向解释器。
多数CGI程序失败的缘由在于程序自己有问题,尤为是在已经消除上述两种错误而CGI挂起的状况下。在用浏览器测试之前,先在命令行中执行你的程序,可以发现大多数的问题。
出错记录是你的朋友。任何错误都会在出错记录中有记载,因此你应该首先查看它。若是你的网站空间提供者不容许访问出错记录,那么你应该考虑换一个空间提供者。学会阅读出错记录,能够快速找出问题并快速解决。
当你的CGI编程逐渐深刻,理解幕后的操做,尤为是浏览器和服务器如何与其余的通信,就变得有用了。虽然成功地写了一个程序打印``Hello, World.'',但并无实际的用处。
环境变量是使用计算机时处处都会用到的变量,好比路径(对实际文件的一个搜索路径以补全你的输入)、你的用户名以及你的终端类型等等。在命令行输入env
,能够获得你的标准的当天的环境变量列表。
在CGI处理过程当中,服务器和浏览器都会设置环境变量,好比浏览器类型(Netscape, IE, Lynx)、服务器类型(Apache, IIS, WebSite)以及将要执行的CGI程序名称等等。
全部这些变量对CGI程序员都有效,但只是客户端-服务器通信的一半内容。完整的变量列表见http://hoohoo.ncsa.uiuc.edu/cgi/env.html
这个简单的CGI程序列出了环境中全部的环境变量,Apache发行版的cgi-bin
中还有两个相似的程序。注意,有些变量是必须的,有些则是可选的,因此你可能会看见一些官方列表中没有的变量。另外,Apache提供了多种不一样方法以在默认提供的变量中增长你的专用环境变量。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
foreach $key (keys %ENV) {
print "$key --> $ENV{$key}<br>";
}
服务器和客户端之间的其余通信都经过标准输入设备(STDIN
)和标准输出设备(STDOUT
)完成。一般,STDIN
是指键盘或者一个程序所做用于的一个文件,STDOUT
指控制台或显示器。
当你POST
一个网络表格到一个CGI程序时,表格中的数据被捆扎为一个特殊形式经过STDIN
传送给CGI程序,这样,这个程序就能够处理这些数据,仿佛这些数据来自键盘或者一个文件。
这种``特殊形式''很简单,一个字段名称及其值,中间用等号(=)链接,多个这样的字段对用与符号(&)链接。很是规字符,如空格、与符号和等号,被转换为其等值的十六进制以避免出问题。整个字串形如:
name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey
有时,你会发现URL后面缀有这样的字串。这种形式会使服务器以这个字串的内容设置环境变量QUERY_STRING
,称为GET
请求。你的HTML表格在FORM
标记中设置METHOD
属性,以指定传送数据的行为使GET
或者是POST
。
接着,你的程序必须把这个字串分离以得到有用的信息。所幸,有库和模块能够帮助你处理这些数据,还有为你的CGI程序达成其余目的的处理器。
编写CGI程序时,你应该考虑使用代码库或模块来完成多数琐碎的工做,以减小错误并更快地开发。
若是用Perl语言编写CGI程序,可用的模块见CPAN,最经常使用的模块是CGI.pm。也能够考虑用CGI::Lite,它实现了一个在多数程序中全部必须的最小功能集
若是用C语言编写CGI程序,则有不少选择,其中之一是CGIC库,来自http://www.boutell.com/cgic/。
网上有大量的CGI资源。能够在Usenet组comp.infosystems.www.authoring.cgi和别人讨论CGI相关问题。HTML Writers Guild的-servers邮件列表是一个优秀的问题解答资源。更多资源能够在http://www.hwg.org/lists/hwg-servers/找到。
另外,还能够阅读CGI规范,其中有CGI程序操做的全部细节,原始版本见NCSA,另有一个更新草案见Common Gateway Interface RFC project。
当你向一个邮件列表或者新闻组提交CGI相关问题时,你应该确保提供了足够的信息以更简单地发现并解决问题,诸如:发生了什么事、你但愿获得什么结果、结果与你所指望的有什么出入、你运行的服务器、CGI程序是用什么语言编写的、若是可能就提供那个讨厌的代码。
注意,毫不要把CGI相关问题提交到Apache bug database,除非你坚信发现的是Apache源代码中的问题。