"); //-->
CGI 全称为Common Gateway Interface (通用网关接口),目的是能够让服务器能够方便的调用外部程序。
CGI本身是一套协议和规范,原则上只要是拥有读写文件功能的编程语言都可以用来编写CGI程序,例如C,C++,Perl,Visual Basic,Shell等等,历史上用来编写CGI程序使用最广泛的是Perl语言,连PHP一开始也是用Perl编写的,估计也受这个传统的影响。服务器在认为这是一个CGI请求时,会调用相关CGI程序,并通过环境变量和标准输出将数据传送给CGI程序,CGI程序处理完数据,生成html,然后再通过标准输出将内容返回给服务器,服务器再将内容交给用户,CGI进程退出,在这个过程中,服务器的标准输出对应了CGI程序的标准输入,CGI程序的标准输出对应着服务器的标准输入,相当于利用两条管道建立了进程间的通信。
CGI程序可能会调用其它应用或API来完成用户提交的请求。
现在CGI一般不再用于直接返回html页面,同时将复杂的计算、IO任务下沉到后端。使CGI作为前后端之间的中间层。彼时CGI的职能是完成基本的数据交换:解析前端数据请求,再转发给对应后端;然后从后端取回数据,给前端返回XML或JSON。
参考:
https://blog.csdn.net/zhang197093/article/details/73555895
https://www.jdon.com/idea/cgi.htm
测试环境:Ubuntu gnome(16.04)版 + win10 (win10上运行Ubuntu虚拟机)
1. 安装thttpd
参考:https://blog.csdn.net/u012247418/article/details/90137417
2. 编写index.html
<h1>A Simple CGI Test</h1> <form action="/cgi-bin/test-cgi.cgi" method="get"> <table> <tr> <td>User Name: </td> <td><input name="username"/></td> </tr> <tr> <td>Password: </td> <td><input name="password"/></td> </tr> <tr> <td><input type="submit" value="OK"/></td> </tr> </table> </form>
利用GET向服务器发送请求,并将用户数据(Name&Password)作为URL的一部分发送到服务器。
3. 编写CGI程序
CGI程序可以用多种语言来编写,当然也包括C/C++。
1) test-cgi.c
#include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char *argv[]) { char *query_string = "FAILD"; char *request_mthod = getenv("REQUEST_METHOD"); if((request_mthod != NULL) && (strncmp(request_mthod, "GET", 3) == 0)) { query_string = getenv("QUERY_STRING"); } printf("Content-type:text/html\n\n"); printf("<html>\n"); printf("<head><title>An html page from a cgi</title></head>\n"); printf("<body>\n"); printf("<h1>query string: %s</h1>\n", query_string); printf("</body>\n"); printf("</html>\n"); fflush(stdout); return 0; }
先判断客户端请求是否为“GET”,如果是则获取请求参数,最后将请求参数再原封不动的返回至客户端。
2) 编译:gcc test-cgi.c -o test-cgi.cgi
4. 修改配置
4.1 创建目录
baoli@ubuntu:~/tools/thttpd/html1$ tree
.
├── cgi-bin
│ └── test-cgi.cgi
└── index.html
1 directory, 2 files
4.2 修改thttpd.conf
# This section overrides defaults dir=/home/baoli/tools/thttpd/html1 # chroot user=baoli# default = nobody logfile=/var/log/thttpd.log pidfile=/var/run/thttpd.pid # This section _documents_ defaults in effect # port=80 # nosymlink# default = !chroot # novhost cgipat=/cgi-bin/* # nothrottles # host=0.0.0.0 # charset=iso-8859-1
说明:
1)cgipat=/cgi-bin/*
声明CGI程序的目录,这里的'/'根目录并非Ubuntu系统的根目录,而是以dir=/home/baoli/tools/thttpd/html1 作为根目录。
2)屏蔽chroot是为了运行动态编译的CGI程序
5. 测试
在windows 浏览器输入:http://192.168.0.104
6. CGI环境变量
环境变量
意义
SERVER_NAME
CGI脚本运行时的主机名和IP地址.
SERVER_SOFTWARE
你的服务器的类型如: CERN/3.0 或 NCSA/1.3.
GATEWAY_INTERFACE
运行的CGI版本. 对于UNIX服务器, 这是CGI/1.1.
SERVER_PROTOCOL
服务器运行的HTTP协议. 这里当是HTTP/1.0.
SERVER_PORT
服务器运行的TCP口,通常Web服务器是80.
REQUEST_METHOD
POST 或 GET, 取决于你的表单是怎样递交的.
HTTP_ACCEPT
浏览器能直接接收的Content-types, 可以有HTTP Accept header定义.
HTTP_USER_AGENT
递交表单的浏览器的名称、版本 和其他平台性的附加信息。
HTTP_REFERER
递交表单的文本的 URL,不是所有的浏览器都发出这个信息,不要依赖它
PATH_INFO
附加的路径信息, 由浏览器通过GET方法发出.
PATH_TRANSLATED
在PATH_INFO中系统规定的路径信息.
SCRIPT_NAME
指向这个CGI脚本的路径, 是在URL中显示的(如, /cgi-bin/thescript).
QUERY_STRING
脚本参数或者表单输入项(如果是用GET递交). QUERY_STRING 包含URL中问号后面的参数.
REMOTE_HOST
递交脚本的主机名,这个值不能被设置.
REMOTE_ADDR
递交脚本的主机IP地址.
REMOTE_USER
递交脚本的用户名. 如果服务器的authentication被激活,这个值可以设置。
REMOTE_IDENT
如果Web服务器是在ident (一种确认用户连接你的协议)运行, 递交表单的系统也在运行ident, 这个变量就含有ident返回值.
CONTENT_TYPE
如果表单是用POST递交, 这个值将是 application/x-www-form-urlencoded. 在上载文件的表单中, content-type 是个 multipart/form-data.
CONTENT_LENGTH
对于用POST递交的表单, 标准输入口的字节数.
关于GET和POST
表单从浏览器发给服务器有两种方法. GET 和 POST.
我们上面谈论的方法,实际是GET,它将数据打包放置在环境变量QUERY_STRING中作为URL整体的一部分传递给服务器。
POST做很多类似GET同样的事情, 不同的地方就是它是分离地传递数据给脚本. 你的脚本通过标准输入获取这些数据. (有些Web服务器是存储在临时文件中.) 这个QUERY_STRING环境变量将不再设置.
那你用那个方法呢? POST是个安全的方法, 尤其如果你的表单中有很多数据的话. 当你用GET, 这个服务器就分配变量QUERY_STRING给所有的表单数据, 但是这个变量可存储量是有限的. 换句话说,如果你有很多数据但是你又用GET,你会丢失很多数据.
————————————————
原文链接:https://blog.csdn.net/u012247418/article/details/90137386
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。