第一个CGI程序
————完全就是普通的C语言嘛
上一篇博文里面叙述了Apache的安装和配置方法,恍恍惚惚我就拥有了自己的第一个http服务器。虽然是局域网下的网站但给同学们开开车还是完全够了(咳咳)。好像是有了Apache再把HTTP文档丢到htdocs文件夹就可以了,老司机的工作竟然如此轻松。其实还有很多的姿势都还没有掌握哦,不追求新姿势的人生和咸鱼有什么分别!就是老司机也要做姿势最多的那一个。这一篇我们一起来了解一下什么是动态网页,什么是CGI。
1.动态网页?那么CGI是什么呢
当网站越来越大,人们终于一如以往的怠惰起来。那一天,大家终于厌烦了一遍遍的制作相似的HTML文档,抱怨着两个文档只有少许的不同就要重写一分,他们开始感到被HTML支配的恐惧,空气的丝缕间溢出的都是绝望的气息。一个俊俏的少年看着无力的人们,说“为什么不写个程序或者脚本来产生HTML呢?”。只一句,浓雾炸裂,日月恢复了昔日的光华。
能够根据用户的请求动态生成的网页就是动态网页(而不是利用Javascript实现动态交互的网页)。现在已经到处都是这种方法的影子,哪些以.asp、.jsp、.php、.cgi等结尾的页面便是动态生成的(不也这些结尾不代表就不是)。当用户向服务器请求时,服务器根据请求的参数调用运行在服务器上的外部程序来生成页面内容(可以想象这个程序就是一般的程序或脚本,他也许仅仅是处理请求的内容,他也许要访问数据库,他可以做他想做的一切)。CGI是一种接口,他说明了外部程序如何被服务器调用。具体的就是,参数如何传入,处理后的信息如何返回。一般说"CGI程序"是指用C/C++写成的*.cgi程序(就是把编译后的*.exe直接改后缀为*.cgi。实际上我才不管你是什么语言,只要编译成.exe就行)。但是严格地讲CGI不是指哪一种语言写成的程序或脚本,而是凡是能满足CGI接口的语言写成的程序或脚本都叫CGI程序,可以是PHP,python等。
2.环境变量 和 标准输入输出
一次web请求在HTTP层面就是三部分:请求行、消息报头、请求正文(下一篇博文讨论HTTP协议,欢迎赏光)。请求行和消息报头的一些信息通过环境变量传递给CGI程序,请求正文则以标准输入的方式传给CGI程序,最后,输出消息以标准输出的方式传出并使用HTTP协议发送给客户(当然可以没有输出)。标准输入输出大家一定不陌生,就是printf(),cin,cout。环境变量是操作系统层面的"全局变量",任何程序都可以注册新的环境变量或访问已有的环境变量,正因如此环境变量成为进程之间交互的一种方式。
在stdlib.h中声明了库函数getenv()用于根据环境变量的名字(char*)获取环境变量,原型如下
char * getenv(const char *name);
举个例子吧,装过JAVA的都知道要设置一个名叫Path的环境变量,我们就用这个函数来获取Path的内容,仅作为该函数的演示。
#include <cstdlib>
#include <iostream>
int main()
{
std::cout << getenv("path")<<std::endl;
return ;
}
图1.运行结果
如果本程序编译出现问题,请参看:解决This function or variable may be unsafe
3.第一个CGI程序
CGI需要用到的环境变量有哪些呢,我们来写第一个CGI程序,它的功能就是返回所有的需要用到的环境变量。这些环境变量其实很多都是HTTP协议的报头,欢迎参看:HTTP协议解析。
首先定义一个结构数组以方便一会输出,如图。
for (int i = ; i < ; i++) {
std::cout << "<li style = \"color:blue\">";
_dupenv_s(&env, &length, nevName[i].name.c_str());
std::cout << nevName[i].name << ':';
if (env == nullptr) {
std::cout << "<br/>";
}else {
std::cout <<"<span style = \"color:green\">" <<env
std::cout <<"</span>"<< "<br/>";
}
//使用一个循环依次输出各项的内容
图2.定义结构数组
编译后把exe文件放到Apache的cgi-bin文件夹中,再写一个HTML来请求这个程序。并把文件放到htdocs文件夹。
<html>
<head><title>第一个CGI</title></head>
<body>
<form action = "/cgi-bin/firstCGI.cgi" method="post">
<input type ="submit">
</form>
</body>
</html>
执行结果:
图3.点击按钮之前
图4.点击提交之后