上一页 下一页

CGI 脚本工作原理

表单:发送输入

我们已经看到创建 CGI 脚本非常简单。Web 服务器会执行放置在 cgi-bin 目录中的任何可执行文件,并且可执行文件发送到标准输出的任何内容都会显示在调用该脚本的浏览器中。现在我们需要一种向脚本发送输入的方法。发送输入的通常方法是使用 HTML 表单

您在网络上随处可见表单。任何可以输入内容的页面都是表单。您在搜索引擎、留言簿、问卷调查等地方都能看到它们。十万个为什么.com 的主页至少包含两个迷你表单,一个用于“您是如何来到这里的?”侧边栏,另一个用于建议侧边栏(是的,单个 HTML 页面可以包含多个表单)。您在 HTML 页面上创建表单,并在表单的 HTML 标签中指定当用户点击表单上的提交按钮时要调用的 CGI 脚本的名称。用户在表单中输入的值将被打包并发送到脚本,脚本可以根据需要使用它们。

广告

您实际上一直都在看到这种事情,可能并不知道它正在发生。例如,访问 http://www.lycos.com,在“搜索内容:”框中输入“test”一词,然后点击“获取!”按钮。结果页面的 URL 将如下所示

http://www.lycos.com/cgi-bin/pursuit?matchmode=and
                    &cat=lycos&query=test&x=10&y=9

您可以看到 Lycos 主页是一个表单。Lycos 在 cgi-bin 目录中有一个名为 pursuit 的脚本。该表单向脚本发送五个参数

  1. matchmode=and
  2. cat=lycos
  3. query=test
  4. x=10
  5. y=9

第三个是我们输入的搜索字符串。其他四个对脚本也有意义。CGI 脚本会查询 Lycos 数据库中“test”一词,然后返回结果。这就是任何搜索引擎的核心!

让我们创建一个简单的表单来试一试。创建一个名为 simpleform.htm 的文件,并在其中输入以下 HTML 代码

<html>
<body>
  <h1>A super-simple form<h1>
  <FORM METHOD=GET ACTION="https://www.十万个为什么.com/
cgi-bin/simpleform.cgi">
  Enter Your Name:
  <input name="Name" size=20 maxlength=50>
  <P>
  <INPUT TYPE=submit value="Submit">
  <INPUT TYPE=reset value="Reset">
  </FORM>
</body>
</html>

该 HTML 代码指定创建一个使用 GET 方法发送到 CGI 脚本 https://www.十万个为什么.com/cgi-bin/simpleform.cgi 的表单。表单内部有一个文本输入区域以及标准的提交和重置按钮。

表单引用的文件 https://www.十万个为什么.com/cgi-bin/simpleform.cgi 是一个 C 程序。它最初是放在名为 simpleform.c 的文件中的这段 C 代码

#include <stdio.h>
#include <stdlib.h>

int main()
{
  printf("Content-type: text/html\n\n");
  printf("<html>\n");
  printf("<body>\n");
  printf("<h1>The value entered was: ")
  printf("%s</h1>\n", getenv("QUERY_STRING"));
  printf("</body>\n");
  printf("</html>\n");
  return 0;
}

它是用以下命令编译的

gcc simpleform.c -o simpleform.cgi

并放置在 cgi-bin 目录中。该程序只是获取表单发送的值并显示出来。例如,您可能会看到以下内容

The value entered was: Name=John+Smith

Name 是表单中文本输入字段的标识符(表单上的每个输入字段都应具有唯一的标识符),John+Smith 是表单中可能输入的典型名称。请注意,“+”号替换了空格字符。

从这个例子可以看出,设置表单并将数据从表单获取到 CGI 脚本的基本过程相当简单。以下是需要注意的几个细节

  • 表单上的每个输入字段都应具有唯一的标识符。
  • 表单需要使用 GET 或 POST 方法。GET 方法的优点是您可以在发送到脚本的 URL 中看到表单的值,这使得调试更容易。
  • 通过 GET 方法发送的字符数量有明确限制,因此对于大型表单,更推荐使用 POST。
  • 通过 GET 方法传入的数据通过查看 QUERY_STRING 环境变量(通常在 C 语言中使用 getenv 函数或在 PERL 中使用 $ENV 功能读取)接收。通过 POST 方法传入的数据通过 STDIN 可用,在 C 语言中使用 gets 或在 PERL 中使用 read
  • 传入的数据将把所有字段连接成一个字符串,并且许多字符将被替换,因此需要转换。例如,所有空格都将替换为加号。

QUERY_STRING 环境变量引出了环境变量的一般话题。您可以在 CGI 脚本中检查许多环境变量,包括

  • AUTH_TYPE
  • CONTENT_LENGTH
  • CONTENT_TYPE
  • GATEWAY_INTERFACE
  • HTTP_ACCEPT
  • HTTP_USER_AGENT
  • PATH_INFO
  • PATH_TRANSLATED
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_HOST
  • REMOTE_IDENT
  • REMOTE_USER
  • REQUEST_METHOD
  • SCRIPT_NAME
  • SERVER_NAME
  • SERVER_PORT
  • SERVER_PROTOCOL
  • SERVER_SOFTWARE

这些环境变量中隐藏着各种有趣的信息,包括输入字符串的长度 (CONTENT_LENGTH)、使用的方法(GET 或 POST -- REQUEST_METHOD 让您判断是查看 STDIN 还是 QUERY_STRING 获取输入)、用户机器的 IP 地址 (REMOTE_ADDR) 等等。有关这些变量的完整描述,请参阅 CGI 环境变量