cgi 订阅
公共网关接口(Common Gateway Interface,CGI)是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。CGI 应用程序能与浏览器进行交互,还可通过数据API与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据。格式化为HTML文档后,发送给浏览器,也可以将从浏览器获得的数据放到数据库中。几乎所有服务器都支持CGI,可用任何语言编写CGI,包括流行的C、C ++、Java、VB 和Delphi 等。CGI分为标准CGI和间接CGI两种。标准CGI使用命令行参数或环境变量表示服务器的详细请求,服务器与浏览器通信采用标准输入输出方式。间接CGI又称缓冲CGI,在CGI程序和CGI接口之间插入一个缓冲程序,缓冲程序与CGI接口间用标准输入输出进行通信 [1]  。 展开全文
公共网关接口(Common Gateway Interface,CGI)是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。CGI 应用程序能与浏览器进行交互,还可通过数据API与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据。格式化为HTML文档后,发送给浏览器,也可以将从浏览器获得的数据放到数据库中。几乎所有服务器都支持CGI,可用任何语言编写CGI,包括流行的C、C ++、Java、VB 和Delphi 等。CGI分为标准CGI和间接CGI两种。标准CGI使用命令行参数或环境变量表示服务器的详细请求,服务器与浏览器通信采用标准输入输出方式。间接CGI又称缓冲CGI,在CGI程序和CGI接口之间插入一个缓冲程序,缓冲程序与CGI接口间用标准输入输出进行通信 [1]  。
信息
外文名
Common Gateway Interface
类    别
标准CGI和间接CGI
定    义
Web 服务器运行时外部程序的规范
中文名
公共网关接口
功    能
用来解释处理来自表单的输入信息
学    科
计算机科学
CGI简介
CGI(Common Gateway Interface)公共网关接口,是外部扩展应用程序与 Web 服务器交互的一个标准接口。服务器端与客户端进行交互的常见方式多,CGI 技术就是其中之一。根据CGI标准,编写外部扩展应用程序,可以对客户端浏览器输入的数据进行处理,完成客户端与服务器的交互操作。CGI规范定义了Web服务器如何向扩展应用程序发送消息,在收到扩展应用程序的信息后又如何进行处理等内容。对于许多静态的HTML网页无法实现的功能,通过 CGI可以实现,比如表单的处理、对数据库的访问、搜索引擎、基于Web的数据库访问等等。使用CGI实现客户端与服务器的交互有以下几个标准步骤,具体步骤如下:(1)Web 客户端的浏览器将URL的第一部分解码与Web服务器相连。(2)Web 浏览器将URL的其余部分提供给服务器。(3)Web 服务器将URL转换成路径和文件名。(4)Web 服务器发送 HTML 和别的组成请求页面的文件给客户。一旦页面内容传送完,这个连接自动断开。(5)在客户端,HTML脚本提示用户做动作或输入。当用户响应后,客户请求Web服务器建立一个新的连接。(6)Web 服务器把这些信息和别的进程变量传送给由HTML以URL的形式指定CGI程序。(7)CGI 根据输入作出响应,把响应结果传送给 Web 服务器。(8)Web 服务器把响应的数据传给客户,完成后关闭连接。 [2]  服务器端 CGI 程序接收信息有三种途径:环境变量、命令行和标准输入。其中环境变量是指 CGI 定义一组环境变量,通过环境变量可传递数据。服务器收到来自浏览器的数据,调用 CGI 脚本,CGI 脚本将收到的数据转换成环境变量并从中取出所需要的内容。
标签的 METHOD 属性来决定具体使用哪一种方法。在“METHOD=GET”时,向 CGI 传递表单编码信息的是通过命令来进行的。表单编码信息大多数是通过环境变量 QUERY_STRING 来传递的。若“METHOD=POST”,表单信息通过标准输入来读取。还有一种不使用表单就可以向 CGI 传送信息的方法,那就是把信息直接附在 URL 地址后面,信息和URL 之间用问号(?)来进行分隔。GET 方法是对数据的一个请求,被用于获得静态文档。GET 方法通过将发送请求信息附加在 URL 后面的参数。当 GET 方法被使用时,CGI 程序将会从环境变量 QUERY_STRING获取数据。为了正确的响应客户端发来的请求,CGI 必须对 QUERY_STRING 中的字符串进行分析。当用户需要从服务器获取数据,但服务器上的数据不得改变时,应该用 GET 方法;但是如果请求中的字符串超过了一定长度,通常是 1024 字节,那么这时,只能用 POST 方法。POST 方法:浏览器将通过填写表单将数据传给服务器时一般采用POST 方法。在发送的数据超过 1024 字节时必须采用 POST 方法。当 POST 方法被使用时,Web 服务器向CGI 程序的标准输入 STDIN 传送数据。环境变量 CONTENT_LENGTH 存放着发送的数据长度。CGI 程序必须检查环境变量 REQUEST_METHOD 以确定有没有采用了 POST 方法,并决定是否要读取标准输入STDIN [3]  。
收起全文
精华内容
参与话题
问答
  • CGI简介

    千次阅读 2014-06-19 16:17:23
    1.CGI概念 CGI(Common Gateway Interface: 公用网关接口)规定了Web服务器调用其他可执行程序(CGI 程序)的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互,也就是CGI程序接受Web浏览器发送给Web服务器...

    参考资料:http://wenku.baidu.com/link?url=EFfS5_2geUIFh5cooqY85VOcaDiqN6e0ROAtXU3M-qShA9Iwi42hI7fwTk2g_j5OhJVJYLwKgdox8RGe-Mrg7D8lb-dXswCRLSl_kzvFOAK

    基于参考资料整理,谢谢作者分享。

    1.CGI概念

    CGI(Common Gateway Interface: 公用网关接口)规定了Web服务器调用其他可执行程序(CGI 程序)的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互,也就是CGI程序接受Web浏览器发送给Web服务器的信息,进行处理, 将响应结果再回送给Web服务器及Web浏览器。CGI程序一般完成Web网页中表单(Form)数据的处理、数据库查询和实现与传统应用系统的集成等工作。

    简单来说,从物理上讲cgi实际是运行在web服务器上的一段程序,提供了同客户端html页面的接口,任何符合cgi标准的程序都是cgi程序


    2.CGI接口标准

    CGI接口标准包括标准输入、环境变量、标准输出三部分。 
    2.1标准输入
        CGI程序像其他可执行程序一样,可通过标准输入(stdin)从Web服务器得到输入信息,如Form中的数据,这就是所谓的向CGI程序传递数据的POST方法。这意味着在操作系统命令行状态可执行CGI程序,对CGI程序进行调试。

    2.2环境变量

        操作系统提供了许多环境变量,它们定义了程序的执行环境,应用程序可以存取它们。Web服务器和CGI接口又另外设置了自己的一些环境变量,用来向CGI程序传递一些重要的参数。CGI的GET方法还通过 环境变量QUERY-STRING向CGI程序传递Form中的数据。

        环境变量是文本串(名字/值对),可以被其他程序设置 或者访问。它们是Web服务器传递数据给CGI程序的简单手段,之所以称为环境变量是因为它们是全局变量,任何程序都可以存取它们。

        常用环境变量:

        HTTP-REFERER:调用该CGI程序的网页的URL。
     REMOTE-HOST:调用该CGI程序的Web浏览器的机器名和域名。
     REQUEST-METHOD:指的是当Web服务器传递数据给CGI程序时所采用的方法,分为GET和POST两种方法。GET方法仅通过环境变量 (如QUERY-STRING)传递数据给CGI程序,而POST方法通过环境变量和标准输入传递数据给CGI程序,因此POST方法可较方便地传递较多的数据给CGI程序。 

        SCRIPT-NAME:该CGI程序的名称。
        QUERY-STRING:当使用POST方法时,Form中的数据最后放在QUERY-STRING中,传递给CGI程序。
        CONTENT-TYPE:传递给CGI程序数据的MIME类型,通常为″application/x-www-form-url encodede″,它是从HTML Form中以POST方法传递数据给CGI程序的数据编码类型,称为URL编码类型。
        CONTENT-LENGTH:传递给CGI程序的数据字符数(字节数)。

    2.3标准输出

        CGI程序通过标准输出(stdout)将输出信息传送给Web服务器。传送给Web服务器的信息可以用各种格式,通常是以纯文本或者HTML文本的形式,这样我们就可以在命令行状态调试CGI程序,并且得到它们的输出

    3.CGI的编程实现

    CGI 程序实现一般有如下几个主要步骤:
    (1)根据POST 方法或GET 方法,接收客户端提交的数据。若以POST 方法提交数据,则程序先从CONTENT_LENGTH 环境变量得到数据的字长,然后从标准输入中读取相应长度的字符串即可得到提交的数据。若以GET 方法提交数据,客户端提交的数据被保存在QUERY_STRING 环境变量中, 通过调用函数getenv(“QUERY_STRING”)来读取数据。

    (2)URL 编码的解码。这个过程较为复杂,在URL 编码的规则下:变量之间用“&”分开;变量与其对应值之间用“=”连接,空格符用“+”代替;特殊意义的字符用“%”接相应的十六进制ASCII 码代替。解码即为编码的逆过程。在程序中,对于提取的数据,当发现字符为“+”时,将它转换成空格;当发现字符为“&”时,意味着一个变量/值对的结束,在此处将字符切成几个字符串;当再现字符为“=”时,意味着一个变量/值对的变量名部分的结束,在此再将变量/值对分开。最后将十六进制ASCII 码值表示的特殊字符转换成相应的ASCII 字符。

    (3)根据上一部分解析出来的变量/值对,判断客户端请求的含义,并传送消息给应用程序主进程,来完成客户端请求要完成的任务,如系统参数设置、远端设备控制等;然后应用程序将执行结果返回给CGI 进程,由CGI 进程用printf()函数来产生HTML 源代码, 再把执行结果返回给客户端。将编写好的CGI程序编译成可执行文件放在WEB Server 设置的CGI 目录下,CGI 程序就能被正确地执行。


    下面是一个简单的CGI程序,它将HTML中Form的信息直接输出到Web浏览器。
      # include <stdio.h>
      # include <stdlib.h>
      main()
      {
          int i, n ;
          printf ("Content-type:text/plain\n\n");
          n=0;
          if(getenv("CONTENT-LENGTH"))
              n=atoi(getenv("CONTENT-LENGTH"));
          for (i=0;i<n;i++)
              putchar(getchar());
          putchar ('n');
          fflush(stdout);
      }


    下面对此程序作一下简要的分析
    prinft ("Content-type:text/plain\n\n");
    此行通过标准输出将字符串"Content-type:text/plain\n\n"传送给Web服务器。它是一个MIME头信息,它告诉Web服务器随后的输出是以纯ASCII文本的形式。请注意在这个头信息中有两个新行符,这是因为Web服务器需要在实际的文本信息开始之前先看见一个空行。

           if (getenv("CONTENT-LENGTH"))
            n=atoi (getenv("CONTENT-LENGTH"));
    此行首先检查环境变量CONTENT-LENGTH是否存在。Web服务器在调用使用POST方法的CGI程序时设置此环境变量,它的文本值表示 Web服务器传送给CGI程序的输入中的字符数目,因此我们使用函数atoi() 将此环境变量的值转换成整数,并赋给变量n。请注意Web服务器并不以文件结束符来终止它的输出,所以如果不检查环境变量CONTENT- LENGTH,CGI程序就无法知道什么时候输入结束了。

          for (i=0;i<n;i++)
       putchar(getchar());
         此行从0循环到(CONTENT-LENGTH-1)次将标准输入中读到的每一个字符直接拷贝到标准输出,也就是将所有的输入以ASCII的形式回送给Web服务器。

        通过此例,我们可将CGI程序的一般工作过程总结为如下几点。
    1.通过检查环境变量CONTENT-LENGTH,确定有多少输入;
    2.循环使用getchar()或者其他文件读函数得到所有的输入;
    3.以相应的方法处理输入;
    4.通过"Contenttype:"头信息,将输出信息的格式告诉Web服务器

           5.通过使用printf()或者putchar()或者其他的文件写函数,将输出传送给Web服务器。

    总之,CGI程序的主要任务就是从Web服务器得到输入信息,进行处理,然后将输出结果再送回给Web服务器。

    展开全文
  • 通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。 组成CGI通信系统的是两部分:一部分是html页面,就是在用户端浏览器上显示的页面。另一部分则是运行...

    一.基本原理

     CGI:通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。

    组成CGI通信系统的是两部分:一部分是html页面,就是在用户端浏览器上显示的页面。另一部分则是运行在服务器上的Cgi程序。它们之间的通讯方式如下图:

    服务器和客户端之间的通信,是客户端的浏览器和服务器端的http服务器之间的HTTP通信,我们只需要知道浏览器请求执行服务器上哪个CGI程序就可以了,其他不必深究细节,因为这些过程不需要程序员去操作。

    服务器和CGI程序之间的通讯才是我们关注的。一般情况下,服务器和CGI程序之间是通过标准输入输出来进行数据传递的,而这个过程需要环境变量的协作方可实现。

    1.   服务器将URL指向一个应用程序

    2.   服务器为应用程序执行做准备

    3.   应用程序执行,读取标准输入和有关环境变量

    4.   应用程序进行标准输出

    对于Windows系统而言,还可以通过profile文件进行数据传输(如ini文件),但在这里不做研究。环境变量在CGI中有着重要的地位!每个CGI程序只能处理一个用户请求,所以在激活一个CGI程序进程时也创建了属于该进程的环境变量。


    二.环境变量

           对于CGI程序来说,它继承了系统的环境变量。CGI环境变量在CGI程序启动时初始化,在结束时销毁。

           当一个CGI程序不是被HTTP服务器调用时,它的环境变量几乎是系统环境变量的复制。当这个CGI程序被HTTP服务器调用时,它的环境变量就会多了以下关于HTTP服务器、客户端、CGI传输过程等项目。

           CONTENT_TYPE:如application/x-www-form-urlencoded,表示数据来自HTML表单,并且经过了URL编码。

    ACCEPT:客户机所支持的MIME类型清单,内容如:”image/gif,image/jpeg”

    REQUEST_METHOD:它的值一般包括两种:POST和GET,但我们写CGI程序时,最后还要考虑其他的情况。

    1.POST方法
           如果采用POST方法,那么客户端来的用户数据将存放在CGI进程的标准输入中,同时将用户数据的长度赋予环境变量中的CONTENT_LENGTH。客户端用POST方式发送数据有一个相应的MIME类型(通用Internet邮件扩充服务:Multi-purpose Internet Mail Extensions)。目前,MIME类型一般是:application/x-wwww-form-urlencoded,该类型表示数据来自HTML表单。该类型记录在环境变量CONTENT_TYPE中,CGI程序应该检查该变量的值。

    2.GET方法
           在该方法下,CGI程序无法直接从服务器的标准输入中获取数据,因为服务器把它从标准输入接收到得数据编码到环境变量QUERY_STRING(或PATH_INFO)。

          GET与POST的区别:采用GET方法提交HTML表单数据的时候,客户机将把这些数据附加到由ACTION标记命名的URL的末尾,用一个包括把经过URL编码后的信息与CGI程序的名字分开:http://www.mycorp.com/hello.html?name=hgq$id=1,QUERY_STRING的值为name=hgq&id=1

    有些程序员不愿意采用GET方法,因为在他们看来,把动态信息附加在URL的末尾有违URL的出发点:URL作为一种标准用语,一般是用作网络资源的唯一定位标示。

           环境变量是一个保存用户信息的内存区。当客户端的用户通过浏览器发出CGI请求时,服务器就寻找本地的相应CGI程序并执行它。在执行CGI程序的同时,服务器把该用户的信息保存到环境变量里。接下来,CGI程序的执行流程是这样的:查询与该CGI程序进程相应的环境变量:第一步是request_method,如果是POST,就从环境变量的len,然后到该进程相应的标准输入取出len长的数据。如果是GET,则用户数据就在环境变量的QUERY_STRING里。

    3.POST与GET的区别
           以 GET 方式接收的数据是有长度限制,而用 POST 方式接收的数据是没有长度限制的。并且,以 GET 方式发送数据,可以通过URL 的形式来发送,但 POST方式发送的数据必须要通过 Form 才到发送。

    三.CGI程序实现步骤
    1.从服务器获取数据
         C语言实现代码:

    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <string.h>
    
    
    int get_inputs()
    
    {
    
    int length;
    
    char *method;
    
    char *inputstring;
    
    method = getenv(“REQUEST_METHOD”); //将返回结果赋予指针
    
    if(method == NULL)
    
        return 1;       //找不到环境变量REQUEST_METHOD
    
    if(!strcmp(method, ”POST”))  // POST方法
    
    {
    
        length = atoi(getenv(“CONTENT_LENGTH”)); //结果是字符,需要转换
    
        if(length != 0)
    
        {
    
            inputstring = malloc(sizeof(char)*length + 1) //必须申请缓存,因为stdin是不带缓存的。
    
            fread(inputstring, sizeof(char), length, stdin); //从标准输入读取一定数据
    
    }
    
    }
    
    else if(!strcmp(method, “GET”))
    
    {
    
        Inputstring = getenv(“QUERY_STRING”);   
    
        length = strlen(inputstring);
    
    }
    
    if(length == 0)
    
    return 0;
    
    }

           Perl实现代码:

    $method = $ENV{‘REQUEST_METHOD’};
    
    if($method eq ‘POST’)
    
    {
    
        Read(STDIN, $input, $ENV{‘CONTENT_LENGTH’});
    
    }
    
    if($method eq ‘GET’ || $method eq ‘HEAD’)
    
    {
    
        $input = $ENV{‘QUERY_STRING’};
    
    }
    
    if($input eq “”)
    
    {
    
    &print_form;
    
    exit;
    
    }

           PYTHON代码实现

    #!/usr/local/bin/python
    
    import cgi
    
    def main():
    
    form = cgi.FieldStorage()
    

           Python代码实现更简单,cgi.FieldStorage()返回一个字典,字典的每一个key就是变量名,key对应的值就是变量名的值,更本无需用户再去进行数据解码!

           获取环境变量的时候,如果先判断“REQUEST_METHOD”是否存在,程序会更健壮,否则在某些情况下可能会造成程序崩溃。因为假若CGI程序不是由服务器调用的,那么环境变量集里就没有与CGI相关的环境变量(如REQUEST_METHOD,REMOTE_ADDR等)添加进来,也就是说“getenv(“REQUEST_METHOD”)”将返回NULL!

    2.URL编码

          不管是POST还是GET方式,客户端浏览器发送给服务器的数据都不是原始的用户数据,而是经过URL编码的。此时,CGI的环境变量Content_type将被设置,如Content_type = application/x-www-form-urlencode就表示服务器收到的是经过URL编码的包含有HTML表单变量数据。

    编码的基本规则是

        变量之间用“&”分开;

        变量与其对应值用“=”连接;

        空格用“+”代替;

        保留的控制字符则用“%”连接对应的16禁止ASCII码代替;

        某些具有特殊意义的字符也用“%”接对应的16进制ASCII码代替;

        空格是非法字符;

        任意不可打印的ASCII控制字符均为非法字符。

    例如,假设3个HTML表单变量filename、e-mail和comments,它们的值对应分别为hello、mike@hotmail.com和I’ll bethere for you,则经过URL编码后应为:

    filename=hello&e-mail=hello@hotmail.com&comments=I%27ll+be+there+for+you

    所以,CGI程序从标准输入或环境变量中获取客户端数据后,还需要进行解码。解码的过程就是URL编码的逆变:根据“&”和“=”分离HTML表单变量,以及特殊字符的替换。

        在解码方面:

    PYTHON代码实现是最理想的,cgi.FieldStorage()函数在获取数据的同时就已自动进行代码转换了,无需程序员再进行额外的代码编写。Perl其次,因为在一个现成的Perl库:cgi-lib.pl中提供了ReadParse函数,用它来进行URL解码很简单:

    require ‘cgi-lib.pl’;
    
    &ReadParse(*input);

    CGI数据输出方面:

          CGI程序如何将信息处理结果返回给客户端?这实际上是CGI格式化输出。

          在CGI程序中的标准输出stdout是经过重定义了的,它并没有在服务器上产生任何的输出内容,而是被重定向到客户浏览器,这与它是由C,还是Perl或Python实现无关。

    所以,我们可以用打印来实现客户端新的HTML页面的生成。比如,C的printf是向该进程的标准输出发送数据,Perl和Python用print向该进程的标准输出发送数据。

    (1)   CGI标题

    CGI的格式输出内容必须组织成标题/内容的形式。CGI标准规定了CGI程序可以使用的三个HTTP标题。标题必须占据第一行输出!而且必须随后带有一个空行

    ( 2 )  MIME:

    向标准输出发送网页内容时要遵守MIME格式规则:

    任意输出前面必须有一个用于定义MIME类型的输出内容(Content-type)行,而且随后还必须跟一个空行。如果遗漏了这一条,服务将会返回一个错误信息。(同样使用于其他标题)

    例如Perl和Python:

    print “Content-type:text/html\n\n”;   //输出HTML格式的数据
    
    print “<body>welcome<br>”
    
    print “</body>”

    C语言:

    printf( “Content-type:text/html\n\n”);
    
    printf(“Welcome\n”);

    MIME类型以类型/子类型(type/subtype)的形式表示。

    其中type表示一下几种典型文件格式的一种:

    Text、Audio、Video、Image、Application、Mutipart、Message

    Subtype则用来描述具体所用的数据格式。

     

    Location

    使用Location标题,一个CGI可以使当前用户转而访问同一服务器上的另外一个程序,甚至可以访问另外一个URL,但服务器对他们的处理方式不一样。

    使用Location的格式为:Location:Filename/URL,例如:         

           print “Location:/test.html\n\n”;
    
    这与直接链接到test.html的效果是一样的。
    
    print “Location:http://www.chinaunix.com/\n\n”
    
    由于该URL并不指向当前服务器,用户浏览器并不会直接链接到指定的URL,而是给用户输出提示信息。

    HTTP状态码

           表示了请求的结果状态,是CGI程序通过服务器用来通知用户其请求是否成功执行的信息码,本文不做研究。

    就是获得getResponseCode(),一般值在0~200为正常,超过视为不正常或特殊意思

    四.CGI中的信号量和文件锁

           因为CGI程序时公用的,而WEB服务器都支持多进程运行,因此可能会发生同时有多个用户访问同一个CGI程序的情况。比如,有2个用户几乎同时访问同一个CGI程序,服务器为他们创建了2个CGI程序进程,设为进程A和进程B。假如进程A首先打开了某个文件,然后由于某种原因被挂起(一般是由于操作系统的进程调度);而就在进程A被挂起的这段时间内,进程B完成了对文件的整个操作流程:打开,写入,关闭;进程A再继续往下执行,但进程A所操作的文件依旧是原来文件的就版本,此时进程A的操作结果将覆盖进程B的操作结果。

    为了防止这种情况发生,需要用到文件锁或者信号量。

    钥匙文件?

    假如有多个不同的HTML可以调用同一个CGI程序,那么CGI程序如何区分它们呢?一个是通过隐含的INPUT标签。不过觉得这个比较麻烦,因为CGI必须经过一系列解码后才能找到这个隐含INPUT的变量和其值。

    五.设置HTTP服务器以兼容CGI

           用Perl编写的CGI程序后缀为:.pl;Python编写的CGI程序后缀为:.py;而C编写的CGI程序后缀为:.cgi,如果在win下编译出来的是.exe,最好将它重命名为.cgi。这些都是为了HTTP服务能够识别并调用它们。

           当使用appche httpd服务器时,请编辑它的配置文件httpd.conf如下:

           修改AddHandler cgi-script一句为AddHandler cgi-script .cgi .py.pl

    六.关于CGI的C语言库——cgihtml

           Cgihtml是一个应用非常广泛的C语言编写的CGI库。它提供的功能函数如下:

           Read_cgi_input():获取并解析HTML表单输入,返回一个指向某结构体的指针

           Cgi_val():获取每个表单变量的值

           Html_header():输出HTML标题栏

           Html_begin():输出HTML文档的开始部分

           H1():输出一行字符,字体为H1

    Html_end():输出HTML文档的结尾部分。

    #include “cgi-lib.h”

    #include “html-lib.h”

    #include “string-lib.h”

    六.后话

          有的人认为可以用JavaScript来代替CGI程序,这其实是一个概念上的错误。JavaScript只能够在客户浏览器中运行,而CGI却是工作在服务器上的。他们所做的工作有一些交集,比如表单数据验证一类的,但是JavaScript是绝对无法取代CGI的。但可以这样说,如果一项工作即能够用JavaScript来做,又可以用CGI来做,那么绝对要使用JavaScript,在执行的速度上,JavaScript比CGI有着先天的优势。只有那些在客户端解决不了的问题,比如和某个远程数据库交互,这时就应该使用CGI了。

    SSI:一种用来动态输出HTML文本的特殊程序。

    网页里包含有某个变量,提交给服务器后,只有该变量改变。此时我们希望服务器不要把整个页面内容都发送过来,而只需要告诉客户端的浏览器,哪个变量的值便成什么样了,浏览器会自动更新。

    SSI在服务器端运行。

    SSI不需要外部接口,它不像CGI从标准输入接收信息。

    你浏览你的HTML文档时看不到SSI标记,因为它已经被相应的程序输出所替代。

    所有的SSI命令都是嵌入在普通的HTML注释行中的。当服务器无法解释SSI时,它将不解释并直接把文档传给浏览器,由于命令在注释中,故浏览器将忽略它们。而当服务器识别SSI时,它并不将该命令传给浏览器,相反,服务器将从上到下扫描HTML文档,执行每一个嵌入注释的命令,并将命令的执行结果代替原注释。

    <! –注释文本-->。服务器将根本不查看注释,除非已启动SSI。

    与纯注释不同的是,所有的SSI命令都是以#打头。

    <!--#command tagname = “parameter”-- >,command指出服务器做什么,tagname指出参数类型,parameter是该命令的用户定义值。

    The currentdate is<! --#echo var = “DATE.LOCAL”-- >,服务器将向浏览器输出时间。

     

    展开全文
  • CGI详解(原理,配置及访问)

    万次阅读 多人点赞 2017-03-09 18:36:53
    通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。 组成CGI通信系统的是两部分:一部分是html页面,就是在用户端浏览器上显示的页面。另一部分则是运行...

    一.基本原理

    CGI:通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。

    组成CGI通信系统的是两部分:一部分是html页面,就是在用户端浏览器上显示的页面。另一部分则是运行在服务器上的Cgi程序。

    它们之间的通讯方式如下图:

    服务器和客户端之间的通信,是客户端的浏览器和服务器端的http服务器之间的HTTP通信,我们只需要知道浏览器请求执行服务器上哪个CGI程序就可以了,其他不必深究细节,因为这些过程不需要程序员去操作。

    服务器和CGI程序之间的通讯才是我们关注的。一般情况下,服务器和CGI程序之间是通过标准输入输出来进行数据传递的,而这个过程需要环境变量的协作方可实现。

     

    1.   服务器将URL指向一个应用程序

    2.   服务器为应用程序执行做准备

    3.   应用程序执行,读取标准输入和有关环境变量

    4.   应用程序进行标准输出

     

    对于Windows系统而言,还可以通过profile文件进行数据传输(如ini文件),但在

    这里不做研究。

    环境变量在CGI中有着重要的地位!每个CGI程序只能处理一个用户请求,所以在激

    活一个CGI程序进程时也创建了属于该进程的环境变量。

    二.环境变量

           对于CGI程序来说,它继承了系统的环境变量。CGI环境变量在CGI程序启动时初始化,在结束时销毁。

           当一个CGI程序不是被HTTP服务器调用时,它的环境变量几乎是系统环境变量的复制。

    当这个CGI程序被HTTP服务器调用时,它的环境变量就会多了以下关于HTTP服务器、客户端、CGI传输过程等项目。

     

    与请求相关的环境变量

    REQUEST_METHOD

    服务器与CGI程序之间的信息传输方式

    QUERY_STRING

    采用GET时所传输的信息

    CONTENT_LENGTH

    STDIO中的有效信息长度

    CONTENT_TYPE

    指示所传来的信息的MIME类型

    CONTENT_FILE

    使用Windows HTTPd/WinCGI标准时,用来传送数据的文件名

    PATH_INFO

    路径信息

    PATH_TRANSLATED

    CGI程序的完整路径名

    SCRIPT_NAME

    所调用的CGI程序的名字

    与服务器相关的环境变量

    GATEWAY_INTERFACE

    服务器所实现的CGI版本

    SERVER_NAME

    服务器的IP或名字

    SERVER_PORT

    主机的端口号

    SERVER_SOFTWARE

    调用CGI程序的HTTP服务器的名称和版本号

    与客户端相关的环境变量

    REMOTE_ADDR

    客户机的主机名

    REMOTE_HOST

    客户机的IP地址

    ACCEPT

    例出能被次请求接受的应答方式

    ACCEPT_ENCODING

    列出客户机支持的编码方式

    ACCEPT_LANGUAGE

    表明客户机可接受语言的ISO代码

    AUTORIZATION

    表明被证实了的用户

    FORM

    列出客户机的EMAIL地址

    IF_MODIFIED_SINGCE

    当用get方式请求并且只有当文档比指定日期更早时才返回数据

    PRAGMA

    设定将来要用到的服务器代理

    REFFERER

    指出连接到当前文档的文档的URL

    USER_AGENT

    客户端浏览器的信息

           CONTENT_TYPE:application/x-www-form-urlencoded,表示数据来自HTML表单,并且经过了URL编码。

    ACCEPT:客户机所支持的MIME类型清单,内容如:”image/gif,image/jpeg”

    REQUEST_METHOD:它的值一般包括两种:POSTGET,但我们写CGI程序时,最后还要考虑其他的情况。

    1.POST方法

    如果采用POST方法,那么客户端来的用户数据将存放在CGI进程的标准输入中,同时将用户数据的长度赋予环境变量中的CONTENT_LENGTH。客户端用POST方式发送数据有一个相应的MIME类型(通用Internet邮件扩充服务:Multi-purpose Internet Mail Extensions)。目前,MIME类型一般是:application/x-wwww-form-urlencoded,该类型表示数据来自HTML表单。该类型记录在环境变量CONTENT_TYPE中,CGI程序应该检查该变量的值。

    2GET方法

    在该方法下,CGI程序无法直接从服务器的标准输入中获取数据,因为服务器把它从标

    准输入接收到得数据编码到环境变量QUERY_STRING(或PATH_INFO)。

    GETPOST的区别:采用GET方法提交HTML表单数据的时候,客户机将把这些数

    据附加到由ACTION标记命名的URL的末尾,用一个包括把经过URL编码后的信息与CGI程序的名字分开:http://www.mycorp.com/hello.htmlname=hgq$id=1QUERY_STRING的值为name=hgq&id=1

    有些程序员不愿意采用GET方法,因为在他们看来,把动态信息附加在URL的末尾有

    URL的出发点:URL作为一种标准用语,一般是用作网络资源的唯一定位标示。

     

    环境变量是一个保存用户信息的内存区。当客户端的用户通过浏览器发出CGI请求时,服务器就寻找本地的相应CGI程序并执行它。在执行CGI程序的同时,服务器把该用户的信息保存到环境变量里。接下来,CGI程序的执行流程是这样的:查询与该CGI程序进程相应的环境变量:第一步是request_method,如果是POST,就从环境变量的len,然后到该进程相应的标准输入取出len长的数据。如果是GET,则用户数据就在环境变量的QUERY_STRING里。

    3POSTGET的区别

           以 GET 方式接收的数据是有长度限制,而用 POST 方式接收的数据是没有长度限制的。并且,以 GET 方式发送数据,可以通过URL 的形式来发送,但 POST方式发送的数据必须要通过 Form 才到发送。

    三.CGI程序实现步骤

    1.从服务器获取数据

    C语言实现代码:

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

     

    int get_inputs()

    {

    int length;

    char *method;

    char *inputstring;

     

    method = getenv(“REQUEST_METHOD”); //将返回结果赋予指针

    if(method == NULL)

        return 1;       //找不到环境变量REQUEST_METHOD

    if(!strcmp(method, ”POST”))  // POST方法

    {

        length = atoi(getenv(“CONTENT_LENGTH”)); //结果是字符,需要转换

        if(length != 0)

        {

            inputstring = malloc(sizeof(char)*length + 1) //必须申请缓存,因为stdin是不带缓存的。

            fread(inputstring, sizeof(char), length, stdin); //从标准输入读取一定数据

    }

    }

    else if(!strcmp(method, “GET”))

    {

        Inputstring = getenv(“QUERY_STRING”);   

        length = strlen(inputstring);

    }

    if(length == 0)

    return 0;

    }

    Perl实现代码:

    $method = $ENV{‘REQUEST_METHOD’};

    if($method eq ‘POST’)

    {

        Read(STDIN, $input, $ENV{‘CONTENT_LENGTH’});

    }

    if($method eq ‘GET’ || $method eq ‘HEAD’)

    {

        $input = $ENV{‘QUERY_STRING’};

    }

    if($input eq “”)

    {

    &print_form;

    exit;

    }

           PYTHON代码实现

    #!/usr/local/bin/python

    import cgi

    def main():

    form = cgi.FieldStorage()

     

    Python代码实现更简单,cgi.FieldStorage()返回一个字典,字典的每一个key就是变量名,key对应的值就是变量名的值,更本无需用户再去进行数据解码!

     

           获取环境变量的时候,如果先判断“REQUEST_METHOD”是否存在,程序会更健壮,否则在某些情况下可能会造成程序崩溃。因为假若CGI程序不是由服务器调用的,那么环境变量集里就没有与CGI相关的环境变量(如REQUEST_METHODREMOTE_ADDR等)添加进来,也就是说“getenv(“REQUEST_METHOD”)”将返回NULL

    2URL编码

    不管是POST还是GET方式,客户端浏览器发送给服务器的数据都不是原始的用户数据,而是经过URL编码的。此时,CGI的环境变量Content_type将被设置,如Content_type = application/x-www-form-urlencode就表示服务器收到的是经过URL编码的包含有HTML表单变量数据。

    编码的基本规则是:

    变量之间用“&”分开;

    变量与其对应值用“=”连接;

    空格用“+”代替;

    保留的控制字符则用“%”连接对应的16禁止ASCII码代替;

    某些具有特殊意义的字符也用“%”接对应的16进制ASCII码代替;

    空格是非法字符;

    任意不可打印的ASCII控制字符均为非法字符。

    例如,假设3HTML表单变量filenamee-mailcomments,它们的值对应分别为hellomike@hotmail.comI’ll bethere for you,则经过URL编码后应为:

     

    filename=hello&e-mail=hello@hotmail.com&comments=I%27ll+be+there+for+you

     

     

    所以,CGI程序从标准输入或环境变量中获取客户端数据后,还需要进行解码。解码的过程就是URL编码的逆变:根据“&”和“=”分离HTML表单变量,以及特殊字符的替换。

    在解码方面,PYTHON代码实现是最理想的,cgi.FieldStorage()函数在获取数据的同时就已自动进行代码转换了,无需程序员再进行额外的代码编写。Perl其次,因为在一个现成的Perl库:cgi-lib.pl中提供了ReadParse函数,用它来进行URL解码很简单:

    require ‘cgi-lib.pl’;

    &ReadParse(*input);

     

    3CGI数据输出

    CGI程序如何将信息处理结果返回给客户端?这实际上是CGI格式化输出。

    在CGI程序中的标准输出stdout是经过重定义了的,它并没有在服务器上产生任何的输出内容,而是被重定向到客户浏览器,这与它是由C,还是Perl或Python实现无关。

    所以,我们可以用打印来实现客户端新的HTML页面的生成。比如,Cprintf是向该进程的标准输出发送数据,PerlPythonprint向该进程的标准输出发送数据。

    (1)   CGI标题

    CGI的格式输出内容必须组织成标题/内容的形式。CGI标准规定了CGI程序可以使用

    的三个HTTP标题。标题必须占据第一行输出!而且必须随后带有一个空行。

    标题

    描述

    Content_type   (内容类型)

    设定随后输出数据所用的MIME类型

    Location    (地址)

    设定输出为另外一个文档(URL

    Status      (状态)

    指定HTTP状态码

     

    MIME

    向标准输出发送网页内容时要遵守MIME格式规则:

    任意输出前面必须有一个用于定义MIME类型的输出内容(Content-type)行,而且随后还必须跟一个空行。如果遗漏了这一条,服务将会返回一个错误信息。(同样使用于其他标题)

    例如PerlPython

    print “Content-type:text/html\n\n”;   //输出HTML格式的数据

    print “<body>welcome<br>”

    print “</body>”

    C语言:

    printf( “Content-type:text/html\n\n”);

    printf(“Welcome\n”);

     

    MIME类型以类型/子类型(type/subtype)的形式表示。

    其中type表示一下几种典型文件格式的一种:

    Text、Audio、Video、Image、Application、Mutipart、Message

    Subtype则用来描述具体所用的数据格式。

    Application/msword

    微软的Word文件

    Application/octet-stream

    一种通用的二进制文件格式

    Application/zip

    Zip压缩文件

    Application/pdf

    Pdf文件

    。。。。。。。。。。。。。。。。。。。。。。。。。。

    。。。。。。。。。。。。。。。。。。。。。。。。。

     

    Location:

    使用Location标题,一个CGI可以使当前用户转而访问同一服务器上的另外一个程序,甚至可以访问另外一个URL,但服务器对他们的处理方式不一样。

    使用Location的格式为:Location:Filename/URL,例如:

    print “Location:/test.html\n\n”;

    这与直接链接到test.html的效果是一样的。

     

    print “Location:http://www.chinaunix.com/\n\n”

    由于该URL并不指向当前服务器,用户浏览器并不会直接链接到指定的URL,而是给用户输出提示信息。

     

     

    HTTP状态码:

           表示了请求的结果状态,是CGI程序通过服务器用来通知用户其请求是否成功执行的信息码,本文不做研究。

    四.CGI中的信号量和文件锁

           因为CGI程序时公用的,而WEB服务器都支持多进程运行,因此可能会发生同时有多个用户访问同一个CGI程序的情况。比如,有2个用户几乎同时访问同一个CGI程序,服务器为他们创建了2CGI程序进程,设为进程A和进程B。假如进程A首先打开了某个文件,然后由于某种原因被挂起(一般是由于操作系统的进程调度);而就在进程A被挂起的这段时间内,进程B完成了对文件的整个操作流程:打开,写入,关闭;进程A再继续往下执行,但进程A所操作的文件依旧是原来文件的就版本,此时进程A的操作结果将覆盖进程B的操作结果。

    为了防止这种情况发生,需要用到文件锁或者信号量。

    钥匙文件?

     

    假如有多个不同的HTML可以调用同一个CGI程序,那么CGI程序如何区分它们呢?一个是通过隐含的INPUT标签。不过觉得这个比较麻烦,因为CGI必须经过一系列解码后才能找到这个隐含INPUT的变量和其值。

    五.设置HTTP服务器以兼容CGI

           用Perl编写的CGI程序后缀为:.pl;Python编写的CGI程序后缀为:.py;而C编写的CGI程序后缀为:.cgi,如果在win下编译出来的是.exe,最好将它重命名为.cgi。这些都是为了HTTP服务能够识别并调用它们。

           当使用appche httpd服务器时,请编辑它的配置文件httpd.conf如下:

           修改AddHandler cgi-script一句为AddHandler cgi-script .cgi .py.pl

    六.关于CGI的C语言库——cgihtml

           Cgihtml是一个应用非常广泛的C语言编写的CGI库。它提供的功能函数如下:

           Read_cgi_input():获取并解析HTML表单输入,返回一个指向某结构体的指针

           Cgi_val():获取每个表单变量的值

           Html_header():输出HTML标题栏

           Html_begin():输出HTML文档的开始部分

           H1():输出一行字符,字体为H1

    Html_end():输出HTML文档的结尾部分。

    #include “cgi-lib.h”

    #include “html-lib.h”

    #include “string-lib.h”

    六.后话

    有的人认为可以用JavaScript来代替CGI程序,这其实是一个概念上的错误。JavaScript只能够在客户浏览器中运行,而CGI却是工作在服务器上的。他们所做的工作有一些交集,比如表单数据验证一类的,但是JavaScript是绝对无法取代CGI的。但可以这样说,如果一项工作即能够用JavaScript来做,又可以用CGI来做,那么绝对要使用JavaScript,在执行的速度上,JavaScript比CGI有着先天的优势。只有那些在客户端解决不了的问题,比如和某个远程数据库交互,这时就应该使用CGI了。

     

     

    SSI:一种用来动态输出HTML文本的特殊程序。

    网页里包含有某个变量,提交给服务器后,只有该变量改变。此时我们希望服务器不要把整个页面内容都发送过来,而只需要告诉客户端的浏览器,哪个变量的值便成什么样了,浏览器会自动更新。

    SSI在服务器端运行。

    SSI不需要外部接口,它不像CGI从标准输入接收信息。

    你浏览你的HTML文档时看不到SSI标记,因为它已经被相应的程序输出所替代。

    所有的SSI命令都是嵌入在普通的HTML注释行中的。当服务器无法解释SSI时,它将不解释并直接把文档传给浏览器,由于命令在注释中,故浏览器将忽略它们。而当服务器识别SSI时,它并不将该命令传给浏览器,相反,服务器将从上到下扫描HTML文档,执行每一个嵌入注释的命令,并将命令的执行结果代替原注释。

    <! –注释文本-->。服务器将根本不查看注释,除非已启动SSI

    与纯注释不同的是,所有的SSI命令都是以#打头。

    <!--#command tagname = “parameter”-- >,command指出服务器做什么,tagname指出参数类型,parameter是该命令的用户定义值。

    The currentdate is<! --#echo var = “DATE.LOCAL”-- >,服务器将向浏览器输出时间。





    展开全文
  • CGI接口原理及实现

    千次阅读 2016-10-20 08:46:40
    CGI接口原理及实现  CGI接口原理及实现(2012-12-7 Over)    1.CGI定义:  CGI(CommonGateway Interface)是HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络...
    CGI接口原理及实现

      CGI接口原理及实现(2012-12-7 Over)

      534x132

      1.CGI定义:

      CGI(CommonGateway Interface)是HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上

      2.CGI功能:

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

      3.CGI运行环境:

      CGI程序在UNIX操作系统上CERN或NCSA格式的服务器上运行。 在其它操作系统(如:windows NT及windows95等)的服务器上 也广泛地使用CGI程序,同时它也适用于各种类型机器。

      4.CGI处理步骤:

      ⑴通过Internet把用户请求送到服务器。

      ⑵服务器接收用户请求并交给CGI程序处理。

      ⑶CGI程序把处理结果传送给服务器。

      ⑷服务器把结果送回到用户。

      5.CGI服务器配置:

      在许多服务器cgi-bin是仅能够放置CGI脚本的目录。

      791x212

      在Windows平台上将C或C++写好的程序的Debug或Release版本的.exe程序拷贝到cgi-bin的目录下(如上图所示),将.exe改为.cgi也可同样运行,如下2个图。

      813x184

      817x165

             cgi-bin目录是存放CGI脚本的地方。这些脚本使WWW服务器和浏览器能运行外部程序,而无需启动另一个程序。它是运行在Web服务器上的一个程序,并由来自于浏览者的输入触发。

      CGI程序不是放在服务器上就能顺利运行,如果要想使其在服务器上顺利的运行并准确的处理用户的请求,则须对所使用的服务器进行必要的设置。

             配置:根据所使用的服务器类型以及它的设置把CGI程序放在某一特定的目录中或使其带有特定的扩展名。

      Apache网络服务器配置在/var/www/cgi-bin里(如下图所示笔者电脑的目录位置)。C++编译的可执行文件可以转换成扩展名为.cgi的文件。

      更改初始配置的的方法:

      <Directory"/var/www/cgi-bin">

      AllowOverride None

      Options ExecCGI

      Order allow,deny

      Allow from all

      </Directory>

      <Directory"/var/www/cgi-bin">

      Options All

      </Directory>

      636x298

      6.CGI接口标准包括标准输入、环境变量、标准输出三部分。

     

      介绍

      1.标准输入

      CGI程序像其他可执行程序一样,可通过标准输入(stdin)从Web服务器得到输入信息,如Form中的数据,这就是所谓的向CGI程序传递数据的POST方法。这意味着在操作系统命令行状态可执行CGI程序,对CGI程序进行调试。POST方法是常用的方法。

      2.环境变量

      操作系统提供了许多环境变量,它们定义了程序的执行环境,应用程序可以存取它们。Web服务器和CGI接口又另外设置了自己的一些环境变量,用来向CGI程序传递一些重要的参数。CGI的GET方法还通过环境变量QUERY-STRING向CGI程序传递Form中的数据。

      3.标准输出

      CGI程序通过标准输出(stdout)将输出信息传送给Web服务器。传送给Web服务器的信息可以用各种格式,通常是以纯文本或者HTML文本的形式,这样我们就可以在命令行状态调试CGI程序,并且得到它们的输出。

      7.环境变量

      环境变量是文本串(名字/值对),可以被OSShell或其他程序设置 ,也可以被其他程序访问。它们是Web服务器传递数据给CGI程序的简单手段,之所以称为环境变量是因为它们是全局变量,任何程序都可以存取它们。

      下面是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递交的表单, 标准输入口的字节数.

      REQUEST-METHOD:指的是当Web服务器传递数据给CGI程序时所采用的方法,分为GET和POST两种方法。

      :GET方法仅通过环境变量(如QUERY-STRING)传递数据给CGI程序,而POST方法通过环境变量和标准输入传递数据给CGI程序,因此POST方法可较方便地传递较多的数据给CGI程序。

       

      问题

      GET方法

      通过在URL中嵌入的形式传递参数。对CGI程序而言,在GET method中传递的参数要通过化境变量“QUERY-STRING”来接收。

      1)  参数的内容作为URL信息,用户可以看到;

      2)  有大小的限制。

      POST方法

      CGI程序从标准输入接收参数。与GET方法不同的是,参数的内容从URL信息中不能获得,对于大小也没有限制。

      与GET方法问题1),2)完全相反。

      CONTENT-LENGTH:传递给CGI程序的数据字符数(字节数)。

      在C语言程序中,要访向环境变量,可使用getenv()库函数。例如:
           if (getenv (″CONTENT-LENGTH″))n=atoi(getenv(″CONTENT-LENGTH″));
      请注意程序中最好调用两次getenv():第一次检查是否存在该环境变量,第二次再使用该环境变量。这是因为函数getenv()在给定的环境变量名不存在时,返回一个NULL(空)指针,如果你不首先检查而直接引用它,当该环境变量不存在时会引起CGI程序崩溃。

      8. CGI的工作原理

      CGI是一个WEB服务器提供信息服务的标准接口,通过这样一个接口,WEB服务器能够执行程序,并将程序输出的信息返回给浏览器。因为在WEB网上的数据都是静态的,通过CGI程序能够动态的处理浏览者的请求,如保存用户输入的信息,根据用户信息返回相关的资料等等。当客户端发送一个CGI请求给WEB服务器后,WEB服务器将根据CGI程序的类型决定数据向CGI程序的传送方式,一般来讲是通过标准输入/输出流和环境变量来与CGI程序间传递数据。

      497x283

      CGI输入输出原理

      CGI的输入/输出方法:CGI程序通过标准输入(STDIN)和标准输出(STDOUT)来进行输入输出,STDIN和STDOUT是两个预先定义好的文件指针。你可以利用文件读写函数来对其进行操纵。

      此外CGI程序还通过环境变量来得到输入,只不过环境变量中提供的是一些常用的信息,并且通常不包括用户在WEB页面中输入的信息(除使用下面讲的GET方法时,通过检查环境变量QUERY_STRING来得到输入数据),而STDIN通常用来传递用户输入的信息。

      在输入时所使用的POST/GET方法:在WEB页面向CGI发送数据时通常采用两种方法:GET/POST,GET方法将数据附加在URL后发送,如:/cgi/a_cgi_test.exe your_data,CGI程序通过检查环境变量QUERY_STRING来得到输入数据。

              示例一、下图即是GET方法!

      368x195

      上图的对应程序为:

      //2012-12-5 GET c程序示例..

      void main(void) {// 本程序将用户输入的数据打印出来 fprintf(stdout,"content-type:text/plain\n\n"); // 输出一个CGI标题,这行代码的意义后面会讲解 char *pszMethod; pszMethod =getenv("REQUEST_METHOD"); if(strcmp(pszMethod,"GET") == 0) { //GET method //读取环境变量来获取数据 printf("This is GETMETHOD!\n"); printf("SERVER_NAME:%s\n",getenv("SERVER_NAME")); printf("REMOTE_ADDR:%s\n",getenv("REMOTE_ADDR")); fprintf(stdout,"input data is:%s\n",getenv("QUERY_STRING")); } else { // POST method //读取STDIN来获取数据 intiLength=atoi(getenv("CONTENT_LENGTH")); printf("This is POSTMETHOD!\n"); fprintf(stdout,"input data is:\n"); for(int i=0;i<iLength;i++) { char cGet=fgetc(stdin); fputc(cGet,stdout); } } }

               示例二、下图即是POST程序示例:

      477x119

      442x111

      471x241

      void unencode(char *src, char *last, char *dest) { // str = hello+there%21 此处跳过data=... // last = ; 已到末尾. // dest= ; 空串. //解码原则 //原则1: '+'变' '; //原则2: '%xx'变成对应的16进制ASCII码值; for(; src != last; src++, dest++) { if(*src == '+') { *dest = ' '; } else if(*src == '%') { int code; if(sscanf(src+1, "%2x", &code) != 1) { code = ' '; } *dest = code; src +=2; } else { *dest = *src; } } *dest = '\n'; *++dest = '\0'; } intmain(void) { char *lenstr; char input[MAXINPUT], data[MAXINPUT]; long len; printf("%s%c%c\n","Content-Type:text/html;charset=iso-8859-1",13,10); printf("<TITLE>Response</TITLE>\n"); lenstr =getenv("CONTENT_LENGTH"); printf("CONTENT_LENGTH =%s\n",lenstr); if(lenstr == NULL ||sscanf(lenstr,"%ld",&len)!=1 || len > MAXLEN) { printf("<P>Error ininvocation - wrong FORM probably."); } else { FILE *f; fgets(input, len+1, stdin); //add by ycy从输入流中获取字符串. unencode(input+EXTRA, input+len,data); f = fopen(DATAFILE,"a"); if(f == NULL) { printf("<P>Sorry,cannot store your data."); } else { fputs(data, f); //add byycy 将数据存储在对对应的文件中. } fclose(f); printf("<P>Thank you!Your contribution has been stored."); } return 0; }

          请求过程即是:

      (1)      send发送按钮--->(2)调用post.cgi--->(3)将数据存储在data\data.txt里面。

             示例三、下图即是GET/POST程序示例。

      综合实例:在上面两个程序上的扩展(应用Get方法及QUERY_STRING),

      377x852

      1015x139

      如上两图所示,在表单(cgi接口的表单只是在html语言的基础上用C或C++实现的扩展操作而已)的基础上,提交按钮对应的另一个CGI接口(6.exe或6.cgi),这样通过Get方法及QUERY_STRING参量就可以完成输出操作。

      而POST方法则会将数据送入CGI程序的STDIN输入流。在表单(FORM)中的各个变量都会成为name=value的形式向WEB服务器发送,多个数据间用&分隔,如:name=value&name2=value2。其中名字(name,name2)是Form中定义的INPUT、SELECT或TEXTAREA等标置(Tag)名字,值是用户输入或选择的标置值。

      如上面说讲,在CGI程序输出时必须先输出一个CGI标题,标题共有以下三类:

      ·      Location: 标题,指明输出另一个文档的URL,例如 fprintf(stdout,"Location: \n\n");

      ·      Content-Type: 标题,指明发送的数据的MIME类型,例如 fprintf(stdout,"Content-Type:text/html\n\n");

      ·      Status: 标题,指明HTTP状态码,例如 fprintf(stdout,"Status: 200\n\n");

      注意每种标题后都必须跟一个换行和一个空行。

      MIME类型以类型/子类型的形式来表示,下面是一些常用的类型/子类型的组合:

      ·      Text/plain 普通文本类型

      ·      Text/html HTML格式的文本类型

      ·      Audio/basic 八位声音文件格式,后缀为.au

      ·      Video/mpeg MPEG文件格式

      ·      Video/quicktime QuickTime文件格式

      ·      Image/gif GIF图形文件

      ·      Image/jpeg JPEG图形文件

      ·      Image/x-xbitmap X bitmap图形文件,后缀为.xbm

      有了上面的知识我们就可以写出一些CGI程序,首先需要对输入数据进行分析,方法为:每当找到字符=,标志着一个Form变量名字的结束;每当找到字符& ,标志着一个Form变量值的结束。请注意输入数据的最后一个变量的值不以&结束。这样我们可以将输入数据分解为一组一组的值。

      但随后会发现CGI的输入并不规则,例如有时会出现类似下面格式的输入字符号串:filename=hello&cmd=world+I%27,这是因为浏览器对一些上传的特殊字符进行了编码,所以在将数据分解开后需要进行解码,

           解码规则为

      1)+: 将+转换成空格符;

         2) %xx: 用其十六进制ASCII码值表示的特殊字符(%作为为转意符)。根据值xx将其转换成相应的ASCII字符。对Form变量名和变量值都要进行这种转换。


    转自:http://www.educity.cn/wenda/86802.html

    展开全文
  • C语言CGI编程入门(一)

    万次阅读 2015-01-05 21:11:58
    C语言CGI编程入门(一) http://www.leavesongs.com/WEB/CGIforC_1.html  CGI是指web服务器调用编程语言编写的程序的一个接口。比如我们可以编写一个用户注册的页面,用户将其输入的邮箱、用户名、密码输入...
  • CGI的操作概念  在HTML中,当客户填写了表单,并按下了发送(submit)按钮后,表单的内容被发送到了服务器端,一般的,这时就需要有一个服务器端脚本来对表单的内容 进行一些处理,或者是把它们保存起来,或者是按...
  • Cgi服务

    2019-07-06 09:33:38
    ​ Python和其他脚本语言有一个不同的点,就是自带web服务器,我们在工作当中常用web服务器:Apache...3、在目录对应的命令行启动了cgi服务器: python -m http.server --cgi 4、同一网段就可以访问了 1、同一网段的...
  • CGI简单介绍

    2019-03-14 23:07:31
    一、什么是cgi 最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html。事物总是不断发展,网站也越来越复杂,所以出现动态技术。但是服务器并不能直接运行 ...
  • c语言实现cgi

    千次阅读 2019-02-20 15:00:16
    参考 C语言CGI编程入门(一) 使用C语言的CGI库“CGIC”完成Web开发的各种要求 C语言构建WEB管理系统(三):CGI程序解析GET数据
  • CGI介绍

    千次阅读 2019-08-21 17:17:36
    本文主要介绍CGI的相关知识。 1. 概念、背景及架构 CGI(Common Gateway Interface),即通用网关接口,是WWW技术中最重要的技术之一,是外部应用程序(即CGI程序)与WEB服务器之间的接口标准,负责在CGI程序和Web...
  • cgi详解

    万次阅读 2016-07-09 09:46:52
    当我们在谈到cgi的时候,我们在讨论什么    最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html。事物总是不断发展,网站也越来越复杂,所以出现动态...
  • 从GitHub上面下载源码,可是不知道怎么用,python程序,好多个,相互调用的,我该怎样才能运行起来呢?
  • 从github下载源码需要修改以下几个内容才能运行 刚开始学习android编程,我喜欢看开源的项目,看懂以后再自己写一遍,刚开始从github上clone一个项目的源码,用androidstudio打开,总是会发现各种错误,总结一下,...
  • CGI

    2013-11-24 21:39:58
    一.基本原理 CGI:通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端提交的...另一部分则是运行在服务器上的Cgi程序。 它们之间
  • CGI入门一:使用C++实现CGI程序

    千次阅读 2019-04-18 21:31:10
    为什么需要CGI 最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html。事物总是不 断发展,网站也越来越复杂,所以出现动态技术。但是服务器并不能直接运行 ...
  • 初识CGI程序

    千次阅读 2015-04-10 15:52:09
    What is CGI? The Common Gateway Interface, or CGI, is a set of standards that define how information is exchanged between the web server and a custom script. The CGI specs are currently maintained by ...
  • cgi例子

    千次阅读 2014-03-07 09:54:44
    CGI实例--表单GET与POST示例 GET方法:做一个加法运算,需要接收两个参数 文件get.c如下: #include #include int main(void) {  char *data;  char a[10],b[10];  printf("Content-Type:text/html\n\n");
  • CGI与Web开发

    万次阅读 2016-11-30 10:52:42
    C++后台实践:古老的CGI与Web开发 本文写给C/C++程序猿,也适合其他对历史感兴趣的程序猿 ============================================= 请求行(request line)、请求头部(header)、空行和请求数据四个...
  • HTML Javascript CGI

    千次阅读 2017-12-14 16:32:37
    CGI最近工作需要实现一个web 服务器。用来显示设备参数以及修改参数等简单的功能。由于是嵌入式设备,所以选择了一些小型的web 服务器。shttpd:小型嵌入式web服务器,可以使用C和C++来实现网页。不过完全由C语言来...
  • CGI编程学习

    万次阅读 多人点赞 2013-01-28 11:14:08
    一.基本原理 CGI:通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端...另一部分则是运行在服务器上的Cgi程序。 它们之间的通讯方式如
  • 一个支持 cgi 的简易 http 服务器

    千次阅读 2016-08-26 20:21:35
    代码 github 链接:https://github.com/SummerInSun/big-http1. boa 移植以及使用测试1. 下载 boa-0.94.14rc21.tar.bz2http://www.boa.org/news.html2. 编译安装 解压:tar -xjf boa-0.94.14rc21.tar.bz2 配置:./...
  • boa cgi html

    万次阅读 2012-08-29 13:16:35
    随着Internet技术的兴起,在嵌入式设备的管理与交互中,基于Web方式的应用成为目前的主流,这种程序结构也就是大家非常熟悉的B/S结构,即在嵌入式设备上运行一个支持脚本或CGI功能的Web服务器,能够生成动态页面,在...
  • CGI漏洞攻击手册

    千次阅读 2005-03-20 00:14:00
    在论坛里看到过bamboo写的CGI漏洞利用的文章,我就想把他扩大一些.一直想完善一些再贴上来,但我并没有机会和时间试过所有漏洞,想到论坛里还有那么多同志会来完善的,就取名CGI漏洞攻击手册version-0.02(升级了bamboo的...
  • CGI 安全问题

    千次阅读 2006-06-04 21:24:00
    创建时间:2000-09-22文章属性:转载文章来源:李果锋文章提交:xundi (xundi_at_xfocus.org)姓名:李果锋...用得非常频繁,尤其是将CGI程序与JavaScript结合起来,可以实现强大的功能,正是因为CGI程序的在Server端的
  • CGI原理与实例

    2018-04-13 10:57:36
    CGI原理与实例 友好例文推荐:CGI详解(原理,配置及访问) 目录 CGI原理与实例 CGI结构示意图 CGI程序 CGI程序开发 简要说明 CGI工作原理 CGI环境变量 环境变量列表 环境变量的作用 GET/POST 代码实例1 ...
  • CGI 相关知识

    千次阅读 2009-04-15 15:44:00
    总是在程序中遇到cgi.server_name cgi.script_name 然后就好奇什么是cgi,后来发现这些都是cgi在客户向web服务器post,get时候所请求的参数。 具体呢提供下面内容参考...
  • 初识 CGICGI 简识

    千次阅读 2016-08-17 22:44:39
    什么是 CGICGI是Common Gateway Interface,即 公共网关接口 的简称。公共网关接口(CGI),是一套标准,定义了信息是如何在 Web 服务器和客户端脚本之间进行交换的。公共网关接口(CGI),是一种用于外部网关程序...
  • CGI与fast-CGI的区别

    千次阅读 2015-06-11 09:38:00
    PHP以CGI方式运行时,当一个请求向web server请求动态页时,web server总会fork一个CGI解释器进程进行处理这个请求,进程处理完成之后将结果返回给web server,web server将结果返回并显示出来,进程结束,当用户...
  • c语言之cgi实例

    万次阅读 2011-03-25 15:09:00
    翻译成中文就是通用网关接口,它是网页的后台处理程序,运行在服务器端上,可以用多种语言书写,最常用的就是Perl(因为Perl有强大的字符串处理功能,而CGI程序经常处理许多的字符串)。举个例子来说,通常一般的...
  • perl cgi编程简介

    千次阅读 2014-01-12 20:28:53
    CGI是什么 ? 通用网关接口CGI,是一组标准定义之间交换信息的Web服务器和自定义脚本。 维护NCSA和NCSA CGI规范定义CGI如下: 通用网关接口CGI,是一个标准的外部网关程序接口与信息服务器,如HTTP服务器。 ...

空空如也

1 2 3 4 5 ... 20
收藏数 265,601
精华内容 106,240
关键字:

cgi