CGI介绍

本文主要介绍 CGI 的相关知识。

1 概述

CGI(Common Gateway Interface),即通用网关接口,是 WWW(World Wide Web)技术中最重要的技术之一,是外部应用程序(即 CGI 程序)与 Web 服务器之间的接口标准,负责在 CGI 程序和 Web 服务器之间传递信息。

CGI 是 Web 服务器运行时,调用外部应用程序(即 CGI 程序)的规范,CGI 规范允许 Web 服务器执行外部程序,并将它们的输出发送给 Web 浏览器,CGI 将 Web 的一组简单的静态超媒体文档变成一个完整的、新的交互式媒体,按照 CGI 编写的程序可以扩展 Web 服务器功能。

出现背景:CGI 是比较原始的开发动态网站的方式。由于静态的 HTML 页面无法实现网站的动态内容的生成,所以就需要由 Web 服务器调用 CGI 程序,CGI 程序生成动态内容,返回给 Web 服务器,Web 服务器再返回给 Web 浏览器。

CGI 应用程序能通过 Web 服务器与 Web 浏览器进行交互,还可以通过数据库 API 与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据,将数据格式化为 HTML 文档后,发送给 Web 浏览器,也可以将从 Web 浏览器获得的数据放到数据库中。CGI 与这几者的关系图如下:

几乎所有 Web 服务器都支持 CGI,可用多种语言编写 CGI(包括流行的 C、C++ 等),只要这种语言具有标准输入、输出和环境变量即可。

大多数的 CGI 程序被用来解释处理来自表单的输入信息,并在服务器产生相应的处理,或将相应的信息反馈给 Web 浏览器,CGI 程序使网页具有了交互功能。

2 CGI程序处理步骤

CGI 程序的一般处理步骤如下:

  1. Web 浏览器通过 HTML 表单或超链接,请求指向一个 CGI 应用程序的 URL;
  2. Web 服务器收到 Web 浏览器发送的请求;
  3. Web 服务器调用(执行)指定 CGI 应用程序;
  4. CGI 应用程序根据相关信息(通常是基于 Web 浏览者输入的内容),执行具体的操作;
  5. CGI 应用程序把操作结果格式化为 Web 服务器和 Web 浏览器能够理解的文档(通常是 HTML 网页),并发送给 Web 服务器;
  6. Web 服务器把操作结果返回给 Web 浏览器。

由于环境变量的大小是有一定限制的,当需要传送的数据量很大时,环境变量的存储空间可能不足,造成传输数据不完整,甚至无法执行 CGI 程序的现象。因此,后来又发展出另外一种方法: POST,也就是利用 I/O 重新导向的技巧,让 CGI 程序可以由 STDIN 和 STDOUT 直接跟 Web 浏览器沟通。当使用这种方法传递请求的数据时,Web 服务器收到数据后,会先将这些数据放在一块输入缓冲区中,并且将数据的大小记录在 CONTENT_LENGTH 环境变量中,然后调用 CGI 程序并将 CGI 程序的 STDIN 指向这块缓冲区,于是我们就可以很顺利的通过 STDIN 和环境变量 CONTENT_LENGTH 得到服务器接收的信息,避免了对传输信息大小的限制。

3 CGI的优缺点

CGI 可以提供许多 HTML 无法做到的功能,比如记数器、顾客信息表格的提交以及统计、搜索程序、Web 数据库等。

用 HTML 是没有办法记住客户的任何信息的,要把客户的信息记录在服务器的硬盘上,就要用到 CGI,这是 CGI 最重要的作用,它补充了 HTML 的不足——仅仅是补充,不是替代。

CGI 使外部程序与 Web 服务器之间交互成为可能, CGI 程序运行在独立的进程中,并对每个 Web 请求建立一个进程,这种方法非常容易实现,但效率很差,难以扩展。当面对大量请求时,进程的大量建立和消亡会使操作系统性能大大下降,此外,由于地址空间无法共享,也限制了资源重用。

为了解决 CGI 存在的上述问题,出现了 CGI 的升级版 FastCGI,关于 FastCGI 的相关内容,请参考此文

  • 17
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CGI(Common Gateway Interface)是一种常见的Web编程技术,可以让Web服务器调用外部程序实现动态网页。本文将介绍如何使用C语言实现一个简单的通讯录管理系统。 首先,需要在Web服务器上配置好CGI环境。这里以Apache服务器为例,可以在httpd.conf文件中添加如下配置: ``` ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" <Directory "/usr/local/apache2/cgi-bin"> AllowOverride None Options None Require all granted </Directory> ``` 这样,可以将CGI程序存放在/usr/local/apache2/cgi-bin目录下,并在Web页面中通过访问http://localhost/cgi-bin/program.cgi的方式调用程序。 接下来,编写C语言代码实现通讯录管理系统。这里使用了文件存储数据,因此需要先创建一个contacts.txt文件存放通讯录信息。 程序主要分为两部分:解析HTTP请求和处理通讯录操作。在解析HTTP请求时,需要读取请求方法、请求路径和请求参数等信息,然后根据请求路径调用相应的处理函数。在处理通讯录操作时,需要读取contacts.txt文件中的数据,并根据请求参数进行增删改查等操作。 以下是示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINE 1024 // 解析HTTP请求 void parse_request(char *request_method, char *request_path, char *request_params) { char *request_body = getenv("QUERY_STRING"); if (request_body == NULL) { request_method[0] = '\0'; request_path[0] = '\0'; request_params[0] = '\0'; return; } sscanf(request_body, "%[^&]&%[^&]&%s", request_method, request_path, request_params); } // 处理添加联系人操作 void add_contact(char *params) { FILE *fp; char line[MAX_LINE]; fp = fopen("contacts.txt", "a"); if (fp == NULL) { printf("Content-type: text/plain\n\n"); printf("Failed to open file\n"); return; } sprintf(line, "%s\n", params); fputs(line, fp); fclose(fp); printf("Content-type: text/plain\n\n"); printf("Success"); } // 处理删除联系人操作 void delete_contact(char *params) { FILE *fp1, *fp2; char line[MAX_LINE]; int found = 0; fp1 = fopen("contacts.txt", "r"); if (fp1 == NULL) { printf("Content-type: text/plain\n\n"); printf("Failed to open file\n"); return; } fp2 = fopen("temp.txt", "w"); if (fp2 == NULL) { printf("Content-type: text/plain\n\n"); printf("Failed to open file\n"); fclose(fp1); return; } while (fgets(line, MAX_LINE, fp1) != NULL) { if (strstr(line, params) == NULL) { fputs(line, fp2); } else { found = 1; } } fclose(fp1); fclose(fp2); if (found) { remove("contacts.txt"); rename("temp.txt", "contacts.txt"); printf("Content-type: text/plain\n\n"); printf("Success"); } else { remove("temp.txt"); printf("Content-type: text/plain\n\n"); printf("Contact not found"); } } // 处理修改联系人操作 void update_contact(char *params) { FILE *fp1, *fp2; char line[MAX_LINE]; int found = 0; fp1 = fopen("contacts.txt", "r"); if (fp1 == NULL) { printf("Content-type: text/plain\n\n"); printf("Failed to open file\n"); return; } fp2 = fopen("temp.txt", "w"); if (fp2 == NULL) { printf("Content-type: text/plain\n\n"); printf("Failed to open file\n"); fclose(fp1); return; } while (fgets(line, MAX_LINE, fp1) != NULL) { if (strstr(line, params) == NULL) { fputs(line, fp2); } else { found = 1; sprintf(line, "%s\n", params); fputs(line, fp2); } } fclose(fp1); fclose(fp2); if (found) { remove("contacts.txt"); rename("temp.txt", "contacts.txt"); printf("Content-type: text/plain\n\n"); printf("Success"); } else { remove("temp.txt"); printf("Content-type: text/plain\n\n"); printf("Contact not found"); } } // 处理查询联系人操作 void query_contact(char *params) { FILE *fp; char line[MAX_LINE]; int found = 0; fp = fopen("contacts.txt", "r"); if (fp == NULL) { printf("Content-type: text/plain\n\n"); printf("Failed to open file\n"); return; } while (fgets(line, MAX_LINE, fp) != NULL) { if (strstr(line, params) != NULL) { printf("Content-type: text/plain\n\n"); printf("%s", line); found = 1; break; } } fclose(fp); if (!found) { printf("Content-type: text/plain\n\n"); printf("Contact not found"); } } int main() { char request_method[MAX_LINE], request_path[MAX_LINE], request_params[MAX_LINE]; parse_request(request_method, request_path, request_params); // 根据请求路径调用相应的处理函数 if (strcmp(request_path, "/add") == 0) { add_contact(request_params); } else if (strcmp(request_path, "/delete") == 0) { delete_contact(request_params); } else if (strcmp(request_path, "/update") == 0) { update_contact(request_params); } else if (strcmp(request_path, "/query") == 0) { query_contact(request_params); } else { printf("Content-type: text/plain\n\n"); printf("Invalid request"); } return 0; } ``` 编译并将程序命名为program.cgi,然后将其存放在/usr/local/apache2/cgi-bin目录下。此时,在Web页面中访问http://localhost/cgi-bin/program.cgi/add?name=John&phone=123456789即可添加联系人,访问http://localhost/cgi-bin/program.cgi/query?name=John即可查询联系人信息,以此类推。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liitdar

赠人玫瑰,手有余香,君与吾共勉

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值