通用网关接口CGI |
![]() ![]() |
读完这篇文档之后, 你将对CGI程序需要做什么才能起作用有一个总体的认识.
每次当一个客户按照相应的URL向你的CGI程序发出请求时, 服务器将实时执行它. 你的程序的输出将或多或少被直接发送给客户.
关于CGI的一个常见的错误理解是,你可以向你的程序直接发送命令行参数, 例如
提示符% myprog -qa blorf
CGI中,命令行被用于其它用途,因此你不能这样直接使用. 实际上,CGI使用环境变量发送你的程序参数. 用于这种用途的两个主要的环境变量为:
QUERY_STRING 由URL中第一个 ?后面的所有内容来定义. 它既可以用一个 ISINDEX 文档来提供, 也可以由一个HTML form (带GET action)提供。另外还可以手工嵌入一个指向你的网关的HTML锚链中提供. 这个串通常是一个信息查询, 特别是用户想在archie数据库中查找什么, 或者是被编码的你的GET form的反馈结果.
该字符串是按照标准URL格式编码的:空格变为+, 特殊字符用十六进制数 %xx 表示. 使用时你需要对它进行解码.
如果你的网关不是从一个FORM中解码, 你就需要从命令行中获取已经解码的查询串. 这意味着查询产中的每个单词将是 ARGV 中的不同部分. 例如, 查询串 "forms rule" 将以argv[1]="forms" 和 argv[2]="rule" 的方式传给你的程序. 如果你选择这种方式,在使用数据前就不再需要对它作任何处理了.
对于可以向描述程序传递附加的上下文说明信息的网关,CGI允许在URL中嵌入外部信息. 这种信息一般在URL的路径名后面的"附加"部分. 服务器对这种信息不做任何编码处理.
PATH_INFO 最用用的例子是向CGI程序传送文件位置. 为了说明这一点, 假设在我的服务器上有一个名为/cgi-bin/foobar的 CGI 程序,这个程序能够处理服务器文档根目录下的文件. 我需要告诉 foobar 处理哪个文件. 通过在URL的末尾包含附加的路径信息, foobar 就可以通过PATH_INFO这个环境变量得到文档相对于文档根目录的位置, 或者通过服务器为你生成的环境变量 PATH_TRANSLATED 来得到文档的绝对路径.
我发现初学者编写的CGI程序经常犯的一个错误是没有格式化输出, 因此服务器无法理解这种输出.
CGI程序可以返回很多种文档类型. 它们可以向客户返回图像, HTML文档, 普通文本, 甚至是一段声音. 另外CGI程序也可以返回指向其它文档的链. 客户一方必须知道你发给它的文档是什么类型的,以便选择相应的显示方式. 为了通知客户这一点, 你的 CGI 程序必须告诉服务器它返回的文档的类型.
为了通知服务器你返回的文档类型是一个完整的文档还是指向另一个文档的链结, CGI要求在你的输出中加一个较短的头. 这个头是 ASCII 文本, 包含用回车或换行(或两者)分隔的行,后面在跟一个空行. 输出部分就紧跟在这个空行之后, 保留原来的格式.
在这种情况下, 你必须告诉服务器你将通过 MIME 类型输出哪种格式的文档. 通常的 MIME 类型有针对 HTML 文件的 text/html 类型, 和对 ASCII 文本的 text/plain 类型.
例如, 要向客户返回 HTML 文档, 你的输出应该是:
Content-type: text/html <HTML><HEAD> <TITLE>output of HTML from CGI script</TITLE> </HEAD><BODY> <H1>Sample output</H1> What do you think of <STRONG>this?</STRONG> </BODY></HTML>
和直接输出文档不同, 你只是告诉浏览器到哪里找到另一篇文档, 或者让服务器自动为你显示另一篇文档.
例如, 假设你想指向你的 Gopher 服务器中的一个文件. 这时你应该知道它的完整的 URL 并且输出为:
Content-type: text/html Location: gopher://httprules.foobar.org/0 <HTML><HEAD> <TITLE>Sorry...it moved</TITLE> </HEAD><BODY> <H1>Go to gopher instead</H1> Now available at <A HREF="gopher://httprules.foobar.org/0">a new location</A> on our gopher server. </BODY></HTML>
不过现在的浏览器一般比较智能化, 它们自动为你打开新的文档, 客户将看不到上述的 HTML 内容. 如果你嫌麻烦, 不想输出 HTML 格式, NCSA HTTPd 将输出一个缺省的 HMTL 文档以支持早期的浏览器.
如果你指向的另一篇文档在你自己的服务器上(并且没有访问限制), 你需要做的就更少了, 只要输出一个部分(虚拟) URL 就可以了, 例如:
Location: /dir1/dir2/myfile.html
服务器这时的反应就象是客户根本没有向你的描述程序发送过请求, 而是直接请求http://yourserver/dir1/dir2/myfile.html. 服务器将考虑所有的事情, 例如察看文件类型或发送适当的头. 你自己只要注意输出第二个空行就可以了.
如果你想指向的文档是受访问权限保护的,你需要在 Location: 中指出一个完整的 URL。因为服务器和客户需要重新处理,以确认是否有权访问所指向的文档.
高级使用: 如果你想输出 Expires 或 Content-encoding 这样的头, 你需要确保你的服务器是和 CGI/1.1一起编译的. 把这些内容和 Location 或 Content-type 一起输出, 它们将被返回给客户.
CGI - Common Gateway Interface
cgi@ncsa.uiuc.edu
Copyright: NPACT | ![]() ![]() |