一 什么是CGI

CGI(The Common Gateway Interface):通用网关接口,定义web服务器和客户脚本进行信息交互的一系列标准。

 二 web浏览器

为了了解CGI的概念,让我们来看看当我们单击一个超链接来浏览一个特定的web页或URL的时候,背后会发生什么事?

(1)浏览器首先会链接HTTP web 服务器并且请求一个URL 页面;

(2) WEB服务器将会解析这个URL并且查询请求的文件名,如果找到了请求文件服务器就会将这个文件发送回浏览器,否则发送回一个包含错误信息提示的页面指示你请求的是一个服务器并不包含的文件。

(3)WEB浏览器将接受来自服务器端的响应,并且向发出请求的用户显示接收到的文件。

然而,HTTP服务器也可能会以如何这种方式进行配置,那就是无论什么时候接受到对特定目录下的文件的请求,服务器不会将这个文件发送回客户端,而是它作为一个程序被服务器执行,并产生出输出发送回客户端浏览器进行显示。

CGI(The Common Gateway Interface)是一个标准化的协议,能够使应用程序(通常称为CGI程序或CGI脚本)同web服务器和客户端进行交互。CGI程序能够用Python, PERL, Shell, C or C++等语言来实现。

三 CGI程序结构图

下图简单的展示了CGI程序架构

四 web服务器配置

在你着手写CGI程序之前,确保你的web服务器支持CGI程序并且配置成处理CGI程序。所有的能够被HTTP服务器执行的CGI程序都被存放在预先配置好的目录下面,这个目录叫做CGI目录,并且按照约定命名为 /var/www/cgi-bin,并且约定CGI文件的后缀名为.cgi ,尽管它们是c++可执行文件。

一般的,Apache 服务器在/var/www/cgi-bin目录下配置文件来运行CGI程序,如果你想要声明另外的目录来运行CGI脚本,你需要修改httpd.conf 文件中的部分内容:

<Directory "/var/www/cgi-bin">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory> <Directory "/var/www/cgi-bin">
Options All
</Directory>

五 第一个CGI脚本

以下是一段简短的CGI脚步代码

#include <iostream>
using namespace std; int main ()
{ cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Hello World - First CGI Program</title>\n";
cout << "</head>\n";
cout << "<body>\n";
cout << "<h2>Hello World! This is my first CGI program</h2>\n";
cout << "</body>\n";
cout << "</html>\n"; return 0;
}

编译上述代码并且将二进制可执行文件命名为cplusplus.cgi,保存路径为/var/www/cgi-bin目录下,运行chmod 755 cplusplus.cgi 命令使得该文件为可执行的。现在,如果你点击cplusplus.cgi然后就会产生如下输出:

Hello World! This is my first CGI program

上面的C++程序是一个将输出写入标准输出文件(stdout)的简单程序。这段代码中有一个很重要的一点那就是第一行代码:Content-type:text/html\r\n\r\n,这行被发送回浏览器,指明浏览器显示的文本类型。现在你应该了解了CGI的基本概念了,你也可以使用python写出更多复杂的CGI程序,C++ CGI程序能与其他任何外部系统进行信息交互,例如像RDBMS。

六 HTTP报文头部

这行字符串” Content-type:text/html\r\n\r\n”是发送回浏览器的HTTP报文头部的一部分,所有的HTTP报文头部都有如下格式:

HTTP Field Name: Field Content

For Example
Content-type: text/html\r\n\r\n

下表中包含其他一些重要的HTTP报文信息,这些信息在CGI编程中经常会用到。

Header Description
Content-type: A MIME string defining the format of the file being returned. Example is Content-type:text/html
Expires: Date The date the information becomes invalid. This should be used by the browser to decide when a page needs to be refreshed. A valid date string should be in the format 01 Jan 1998 12:00:00 GMT.
Location: URL The URL that should be returned instead of the URL requested. You can use this filed to redirect a request to any file.
Last-modified: Date The date of last modification of the resource.
Content-length: N The length, in bytes, of the data being returned. The browser uses this value to report the estimated download time for a file.
Set-Cookie: String Set the cookie passed through the string

七 CGI环境变量

所有的CGI程序将会使用到下列的CGI环境变量,这些变量在CGI程序中起着重要的作用。

Variable Name Description
CONTENT_TYPE The data type of the content. Used when the client is sending attached content to the server. For example file upload etc.
CONTENT_LENGTH The length of the query information. It's available only for POST requests
HTTP_COOKIE Return the set cookies in the form of key & value pair.
HTTP_USER_AGENT The User-Agent request-header field contains information about the user agent originating the request. Its name of the web browser.
PATH_INFO The path for the CGI script.
QUERY_STRING The URL-encoded information that is sent with GET method request.
REMOTE_ADDR The IP address of the remote host making the request. This can be useful for logging or for authentication purpose.
REMOTE_HOST The fully qualified name of the host making the request. If this information is not available then REMOTE_ADDR can be used to get IR address.
REQUEST_METHOD The method used to make the request. The most common methods are GET and POST.
SCRIPT_FILENAME The full path to the CGI script.
SCRIPT_NAME The name of the CGI script.
SERVER_NAME The server's hostname or IP Address
SERVER_SOFTWARE The name and version of the software the server is running.

下面这段代码列出了所有的CGI变量,点击Get Environment可看结果。

#include <iostream>
using namespace std; const string ENV[ 24 ] = {
"COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",
"HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING",
"HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION",
"HTTP_HOST", "HTTP_USER_AGENT", "PATH",
"QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
"REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME",
"SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN",
"SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL",
"SERVER_SIGNATURE","SERVER_SOFTWARE" }; int main ()
{ cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>CGI Envrionment Variables</title>\n";
cout << "</head>\n";
cout << "<body>\n";
cout << "<table border = \"0\" cellspacing = \"2\">"; for ( int i = 0; i < 24; i++ )
{
cout << "<tr><td>" << ENV[ i ] << "</td><td>";
// attempt to retrieve value of environment variable
char *value = getenv( ENV[ i ].c_str() );
if ( value != 0 ){
cout << value;
}else{
cout << "Environment variable does not exist.";
}
cout << "</td></tr>\n";
}
cout << "</table><\n";
cout << "</body>\n";
cout << "</html>\n"; return 0;
}

八 C++CGI库

在该FTP服务器上ftp://ftp.gnu.org/gnu/cgicc/ 提供了C++ CGI库以供下载,我们从上面下载CGI 库并一下步骤进行安装:

      $tar xzf cgicc-X.X.X.tar.gz 

$cd cgicc-X.X.X/

$./configure --prefix=/usr

$make

$make install

并且你可以阅读相关文档。C++ CGI Lib Documentation 。

九 GET 与POST方法

当你需要从浏览器客户端传递信息至web服务器端并最终送至CGI程序的时候,你将必然会遇到很多的问题。大部分的浏览器使用两种方法发送信息至浏览器:GET方法和POST方法,进行过WEB开发的人应该对其很熟悉。

1. 使用GET方法发送信息

GET方法将编码过的用户信息附加在页面请求上发送,页面请求和这些编码信息使用?进行分割,如下所示:

http://www.test.com/cgi-bin/cpp.cgi?key1=value1&key2=value2

GET方法是浏览器发送信息之服务器端所采用的默认的方法,采用这种方法发送时,在你的浏览器地址栏上在URL后面会附加上一串字符串,如果你传输密码或其他敏感信息至服务器端的时候不要使用GET方法,GET方法有长度限制,在一个请求字符串中,最多只能发送1024的字符。

当使用GET方法的时候,HTTP报文头采用QUERY_STRING发送信息,并且将通过QUERY_STRING环境变量进入你的CGI程序。

您能够使用简单的键-值组合附加在URL后传递信息,或者你也可使用HTML中的<FORM>标签通过使用GET方法来传递信息。

2. 使用POST方法发送信息

CGI程序中较为通用的且更为可靠地传递信息的方法是POST方法,POST传递的报文信息和GET方法没什么两样,但是跟GET方法的将字符串信息附加于URL之后并且用?分隔有所区别的是,POST方法使用分离的报文段分别发送URL和要传输的信息。这些信息会被CGI脚本以标准输入的形式接收。

(注:在原文中作者给出了HTML各种控件传递信息给CGI脚本的例子,有兴趣的朋友可以去看看)

十 在CGI中使用Cookies

服务器可能会以Cookies的形式发送数据给客户端浏览器上,浏览器也许会接收这些Cookies,并且会以简单文本的形式存储在用户的硬盘上,当用户访问该web站点的另外页面的时候,这些Cookies就会有用处了,服务器就会据此知道用户记录了那些信息。

Cookies信息格式包含如下5个变量:

(1) Expires:包含Cookies的过期信息。如果变量值为空,当客户端关闭浏览器时,Cookies就会过期。

(2)  Domain:web站点的域名信息。

(3)  Path:设置Cookies的web页或目录的路径。如果想要从任何页面或目录获取Cookies信息,此变量设为空值。

(4)  Secure:如果该字段设置为"secure",那么Cookies将只能被安全服务器获取,如果该字段为空,则没有该限制。

(5)  Name=Value:Cookies以键-值对的形式设置或获取。

1. 设置Cookies

发送Cookies信息至浏览器是非常容易的,这些Cookies将会附加在在HTTP报文头的Content-type域前。假设你想要以Cookies的方式设置UserID和Password,那么简单的CGI设置脚本如下:

#include <iostream>
using namespace std; int main ()
{ cout << "Set-Cookie:UserID=XYZ;\r\n";
cout << "Set-Cookie:Password=XYZ123;\r\n";
cout << "Set-Cookie:Domain=www.tutorialspoint.com;\r\n";
cout << "Set-Cookie:Path=/perl;\n";
cout << "Content-type:text/html\r\n\r\n"; cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Cookies in CGI</title>\n";
cout << "</head>\n";
cout << "<body>\n"; cout << "Setting cookies" << endl; cout << "<br/>\n";
cout << "</body>\n";
cout << "</html>\n"; return 0;
}

从这个例子中你将了解怎么设置Cookies,那就是使用Set-Cookie来设置Cookies。

设置Cookies属性的时候,Expires, Domain, and Path是可选的,值得注意的一点是Cookies的设置是在发送"Content-type:text/html\r\n\r\n”之前。运行/cgi-bin/setcookies.cgi将会在你的电脑上设置Cookies。

2.获取Cookies

获取Cookies也非常简单,Cookies都存储在CGI的环境变量HTTP_COOKIE中,并且具有如下的格式:

key1=value1;key2=value2;key3=value3....

以下就是一段获取Cookies的简短的CGI代码:

#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h> #include <cgicc/CgiDefs.h>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h> using namespace std;
using namespace cgicc; int main ()
{
Cgicc cgi;
const_cookie_iterator cci; cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Cookies in CGI</title>\n";
cout << "</head>\n";
cout << "<body>\n";
cout << "<table border = \"0\" cellspacing = \"2\">"; // get environment variables
const CgiEnvironment& env = cgi.getEnvironment(); for( cci = env.getCookieList().begin();
cci != env.getCookieList().end();
++cci )
{
cout << "<tr><td>" << cci->getName() << "</td><td>";
cout << cci->getValue();
cout << "</td></tr>\n";
}
cout << "</table><\n"; cout << "<br/>\n";
cout << "</body>\n";
cout << "</html>\n"; return 0;
}

点击/cgi-bin/getcookies.cgi看看效果,将会显示出之前设置过的Cookies。

译自:http://www.tutorialspoint.com/cplusplus/cpp_web_programming.htm (部分略去未译)。

C++ CGI Helloword的更多相关文章

  1. CGI与FastCGI nginx+PHP-FPM

    本文转载自CGI与FastCGI 1.当我们在谈到cgi的时候,我们在讨论什么 最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html. ...

  2. CGI与FastCGI

    当我们在谈到cgi的时候,我们在讨论什么 最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html.事物总是不 断发展,网站也越来越复杂, ...

  3. React.js 官网入门教程 分离文件 操作无法正常显示HelloWord

    对着React官网的教程练习操作,在做到分离文件练习时,按照官网步骤来却怎么也无法正常显示HelloWord. 经测试,html文件中内容改为: <!DOCTYPE html><ht ...

  4. CGI, FastCGI, WSGI, uWSGI, uwsgi简述

    CGI 通用网关接口(Common Gateway Interface/CGI)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据.CGI描述了服务器和请求处理程 ...

  5. Servlet和CGI的区别

    Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销 ...

  6. fastcgi与cgi的区别

    fastcgi与cgi的区别 先讲下cgi:cgi在2000年或更早的时候用得比较多, 以前web服务器一般只处理静态的请求,如果碰到一个动态请求怎么办呢?web服务器会根据这次请求的内容,然后会fo ...

  7. CGI与fastcgi与php-fpm与php-cgi的关系

    cgi是一个协议,它规定了服务器Nginx会将那些数据传送给PHP-cgi fastcgi也可以说是一个协议.fastcgi是对cgi的性能的一次提高.fastcgi会先启动一个master,解析配置 ...

  8. CGI和ISAPI

    1) CGI概念CGI即通用网关接口(Common Gateway Interface),它是一段程序,运行在服务器上,提供同客户端HTML页面的交互,通俗的讲CGI就象是一座桥,把网页和WEB服务器 ...

  9. CGI概念

    CGI(通用网关接口,Common Gateway Interface) CGI是Web服务器与请求处理程序之间传输数据的一种标准,保证Web服务器传递过来的数据是标准格式的,其程序须运行在网络服务器 ...

随机推荐

  1. java Springmvc ajax上传

    ajax上传方式相对于普通的form上传方式要便捷,在更多的时候都会使用ajax (简单的小示例) 1.要先去下载一个 jquery.ajaxfileupload.js(基于jquery.js上的js ...

  2. 初学dorado

    初学dorado 1.dorado使用视图来写界面代码,超级轻松:还需要画流程,页面间的跳转应该很轻松了. 2.先新建dorado项目,再创建dorado视图 3.在Servers里双击tomacat ...

  3. springmvc学习(一)helloworld实例

    今天介绍的是springmvc的学习,越来越多的企业开始选择springmvc+mybatis来构建系统架构,在电商热门的今天,springmvc+mybatis已成为电商项目架构的很好搭配.Spri ...

  4. spring常用的连接池属性文件配置

    (一) DBCP 引入jar文件 commons-dbcp-1.2.1.jar commons-pool-1.3.jar二个包. spring配置文件 <bean id="dataSo ...

  5. php常用单词语法

    header("Content-type:text/html;charset=utf-8"); 加入数组array_push($ratings_store_cop,$value); ...

  6. PHP连接sqlserver的两种方法,向sqlserver2000中写入数据,中文乱码

    项目环境是php5.3.28 项目用的ThinkPHP3.2.3  已经mysql5.5数据库,要和另一个项目对接,需要连接sqlsever2000数据库进行一些操作. 第一种用php自带扩展连接数据 ...

  7. mysql cluster 安装配置方案

    mysql cluster (mysql 集群)安装配置方案   一.准备 1.准备服务器 计划建立有5个节点的MySQL CLuster体系,需要用到5台服务器,但是我们做实验时没有这么多机器,可以 ...

  8. Ubuntu14.04 LTS安装不成功

    北京时间2014年04月18日早8:00时,Ubuntu14.04 LTS在ubuntu官网放出,果断下之体验. 镜像为ubuntu-14.04-desktop-amd64.iso.大小为964M.M ...

  9. shell脚本加不加export的区别

    加了export: jackyyu@ubuntu:~$ cat 1.sh #!/bin/dash test=test echo ${test} echo ${TERM} TERM=dumb expor ...

  10. PHP生成订单号(产品号+年的后2位+月+日+订单号)

    require '../common.inc.php'; /* * 产品号+年的后2位+月+日+订单数 * @param [Int] $prodcutId 产品号 * @param [Int] $tr ...