新闻  |   论坛  |   博客  |   在线研讨会
WEB通用网关接口:CGI简单教程
电子禅石 | 2021-10-22 09:19:20    阅读:821   发布文章


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


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
属于自己的技术积累分享,成为嵌入式系统研发高手。
推荐文章
最近访客