主页
  • 主页
  • 分类
  • 热文
  • 教程
  • 面试
  • 标签
C++

C++ 基础

C++ 主页
C++ 概述
C++ 环境
C++ 基本语法
C++ 注释
C++ 数据类型
C++ Hello, World
C++ 省略命名空间
C++ 数值类型
C++ 字符类型
C++ 布尔类型
C++ 变量
C++ 作用域
C++ 多个变量
C++ 输入输出基础
C++ 常量/文字
C++ 修饰符类型
C++ 存储类别
C++ 操作符
C++ 决策结构
C++ 循环结构
C++ foreach 循环
C++ 数字
C++ 数组
C++ 指针
C++ 枚举类型
C++ 引用变量
C++ 日期与时间
C++ 结构体
C++ 联合类型

C++ 字符串

C++ 字符串
C++ 字符串长度
C++ 字符串连接

C++ 函数

C++ 函数
C++ 多参数函数
C++ 递归
C++ return 语句
C++ 函数重载
C++ 函数重写

C++ 面向对象

C++ 面向对象
C++ 类和对象
C++ 多重继承
C++ 多层次继承
C++ 继承
C++ 重载
C++ 多态性
C++ 抽象
C++ 封装
C++ 接口

C++ 高级

C++ 文件和流
C++ 异常处理
C++ 动态内存
C++ 命名空间
C++ 模板
C++ 预处理器
C++ 信号量
C++ 多线程
C++ Web 编程
C++ 高级概念

基础

C++ 主页
C++ 概述
C++ 环境
C++ 基本语法
C++ 注释
C++ 数据类型
C++ Hello, World
C++ 省略命名空间
C++ 数值类型
C++ 字符类型
C++ 布尔类型
C++ 变量
C++ 作用域
C++ 多个变量
C++ 输入输出基础
C++ 常量/文字
C++ 修饰符类型
C++ 存储类别
C++ 操作符
C++ 决策结构
C++ 循环结构
C++ foreach 循环
C++ 数字
C++ 数组
C++ 指针
C++ 枚举类型
C++ 引用变量
C++ 日期与时间
C++ 结构体
C++ 联合类型

字符串

C++ 字符串
C++ 字符串长度
C++ 字符串连接

函数

C++ 函数
C++ 多参数函数
C++ 递归
C++ return 语句
C++ 函数重载
C++ 函数重写

面向对象

C++ 面向对象
C++ 类和对象
C++ 多重继承
C++ 多层次继承
C++ 继承
C++ 重载
C++ 多态性
C++ 抽象
C++ 封装
C++ 接口

高级

C++ 文件和流
C++ 异常处理
C++ 动态内存
C++ 命名空间
C++ 模板
C++ 预处理器
C++ 信号量
C++ 多线程
C++ Web 编程
C++ 高级概念

C++ Web 编程


上一章 下一章

一. 什么是 CGI?

通用网关接口(Common Gateway Interface,简称 CGI)是一套定义了 Web 服务器和自定义脚本之间如何交换信息的标准。

CGI 规范由 NCSA(国家超级计算应用中心)维护,NCSA 定义 CGI 如下:

CGI 是一种用于外部网关程序与信息服务器(如 HTTP 服务器)交互的标准。

当前版本为 CGI/1.1,CGI/1.2 正在开发中。

1.1 Web 浏览

为了理解 CGI 的概念,让我们看一下点击超链接以浏览特定网页或 URL 时会发生什么:

  • 浏览器联系 HTTP 服务器,并请求指定的 URL 文件名。
  • Web 服务器解析 URL,并查找相应文件。如果找到请求的文件,Web 服务器将文件返回给浏览器,否则返回错误信息,提示请求的文件不存在。
  • 浏览器接收服务器的响应,显示接收到的文件或错误信息。

然而,可以将 HTTP 服务器设置为,当请求特定目录中的文件时,不发送该文件,而是将其作为程序执行,并将程序的输出返回给浏览器显示。

CGI 是一种标准协议,用于使应用程序(称为 CGI 程序或 CGI 脚本)与 Web 服务器和客户端进行交互。CGI 程序可以用 Python、PERL、Shell、C、C++ 等编写。

二. CGI 架构

2.1 CGI 架构图

以下简单程序展示了 CGI 的基本架构:

2.2 Web 服务器配置

在开始 CGI 编程之前,请确保您的 Web 服务器支持 CGI 并且配置为处理 CGI 程序。所有由 HTTP 服务器执行的 CGI 程序保存在预先配置的目录中。这个目录称为 CGI 目录,通常命名为 /var/www/cgi-bin。按照惯例,CGI 文件的扩展名为 .cgi,尽管它们是 C++ 可执行文件。

默认情况下,Apache Web 服务器配置为在 /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>

在此假设您的 Web 服务器已成功运行,并且您能够运行其他 CGI 程序(例如 Perl 或 Shell)。

三. 第一个 CGI 程序

考虑以下 C++ 程序:

#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 目录中,并具有上述内容。在运行您的 CGI 程序之前,请确保通过 UNIX 命令 chmod 755 cplusplus.cgi 使文件可执行。

这个简单的 C++ 程序将其输出写到 STDOUT,即屏幕。第一个打印的行 Content-type:text/html\r\n\r\n 是一个重要的功能,它将内容类型发送回浏览器,用于指定要在浏览器上显示的内容类型。

现在,您应该已经理解了 CGI 的基本概念,并且可以使用 Python 编写更复杂的 CGI 程序。一个 C++ CGI 程序可以与其他外部系统(如 RDBMS)进行交互,以交换信息。

3.1 HTTP 头信息

Content-type:text/html\r\n\r\n 是 HTTP 头的一部分,它发送给浏览器以便理解内容。所有的 HTTP 头信息将以以下形式出现:

HTTP Field Name: Field Content

例如:

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

四. 常用 HTTP 头信息

以下是一些您在 CGI 编程中会频繁使用的重要 HTTP 头信息。

Sr.No 头信息 描述
1 Content-type: 定义返回文件格式的 MIME 字符串。
2 Expires: Date 信息失效的日期。格式:01 Jan 1998 12:00:00 GMT。
3 Location: URL 返回的 URL 替代请求的 URL,可用于重定向。
4 Last-modified: Date 资源的最后修改日期。
5 Content-length: N 返回数据的字节长度。浏览器使用该值来报告文件的估计下载时间。
6 Set-Cookie: String 通过字符串设置 cookie。

五. CGI 环境变量

所有 CGI 程序都有权访问以下环境变量。这些变量在编写 CGI 程序时非常重要。

Sr.No 变量名称 描述
1 CONTENT_TYPE 客户端发送给服务器的内容数据类型。
2 CONTENT_LENGTH 可用于 POST 请求的查询信息长度。
3 HTTP_COOKIE 返回以键值对形式的设置 cookie。
4 HTTP_USER_AGENT 包含发出请求的用户代理的信息。
5 PATH_INFO CGI 脚本的路径。
6 QUERY_STRING 通过 GET 方法发送的 URL 编码信息。
7 REMOTE_ADDR 发出请求的远程主机的 IP 地址。
8 REMOTE_HOST 发出请求的主机的完整名称。
9 REQUEST_METHOD 用来发出请求的方法。常见方法是 GET 和 POST。
10 SCRIPT_FILENAME CGI 脚本的完整路径。
11 SCRIPT_NAME CGI 脚本的名称。
12 SERVER_NAME 服务器的主机名或 IP 地址。
13 SERVER_SOFTWARE 服务器运行的软件名称和版本。

5.1 列出所有 CGI 变量的程序

#include <iostream>
#include <stdlib.h>
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 Environment 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>";
      
      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 库

对于真实的例子,您可能需要通过 CGI 程序执行许多操作。这里有一个 C++ 编写的 CGI 库,您可以从 GNU FTP 服务器 下载并安装。

$ tar xzf cgicc-X.X.X.tar.gz 
$ cd cgicc-X.X.X/ 
$ ./configure --prefix=/usr 
$ make
$ make install

七. GET 和 POST 方法

您可能遇到过许多需要从浏览器向 Web 服务器传递信息并最终到达 CGI 程序的情况。浏览器最常用的两种方法是 GET 方法和 POST 方法。

7.1 使用 GET 方法传递信息

GET 方法将编码的用户信息附加到页面请求中。页面和编码信息用

一个 ? 作为分隔符。注意,查询字符串的长度受限于大约 255 个字符。

<form method="GET" action="/cgi-bin/cplusplus.cgi">
First Name: <input type="text" name="first_name"> <br />
Last Name: <input type="text" name="last_name" />
<input type="submit" value="提交" />
</form>

7.2 使用 POST 方法传递信息

<form method="POST" action="/cgi-bin/cplusplus.cgi">
First Name: <input type="text" name="first_name"> <br />
Last Name: <input type="text" name="last_name" />
<input type="submit" value="提交" />
</form>

八. 通过 CGI 程序传递单选按钮数据

单选按钮用于当只需要选择一个选项的情况。

以下是带有两个单选按钮的表单的示例 HTML 代码:

<form action="/cgi-bin/cpp_radiobutton.cgi" method="post" target="_blank">
   <input type="radio" name="subject" value="maths" checked="checked" /> Maths 
   <input type="radio" name="subject" value="physics" /> Physics
   <input type="submit" value="Select Subject" />
</form>

该代码生成的表单如下:

Maths Physics

以下是 C++ 程序,它将生成 cpp_radiobutton.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 formData;
  
   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Radio Button Data to CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("subject");  
   if (!fi->isEmpty() && fi != (*formData).end()) {  
      cout << "Radio box selected: " << **fi << endl;  
   }
  
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

九. 通过 CGI 程序传递文本区域数据

TEXTAREA 元素用于将多行文本传递给 CGI 程序。

以下是带有一个 TEXTAREA 框的表单的示例 HTML 代码:

<form action="/cgi-bin/cpp_textarea.cgi" method="post" target="_blank">
   <textarea name="textcontent" cols="40" rows="4">
      Type your text here...
   </textarea>
   <input type="submit" value="Submit" />
</form>

该代码生成的表单如下:

Type your text here...

以下是 C++ 程序,它将生成 cpp_textarea.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 formData;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Text Area Data to CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("textcontent");
   if (!fi->isEmpty() && fi != (*formData).end()) {
      cout << "Text Content: " << **fi << endl;
   } else {
      cout << "No text entered" << endl;
   }

   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

十. 通过 CGI 程序传递下拉框数据

下拉框用于当有多个选项但只需要选择一个或两个的情况。

以下是带有一个下拉框的表单的示例 HTML 代码:

<form action="/cgi-bin/cpp_dropdown.cgi" method="post" target="_blank">
   <select name="dropdown">
      <option value="Maths" selected>Maths</option>
      <option value="Physics">Physics</option>
   </select>
   
   <input type="submit" value="Submit"/>
</form>

该代码生成的表单如下:

Maths

以下是 C++ 程序,它将生成 cpp_dropdown.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 formData;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Drop Down Box Data to CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("dropdown");
   if (!fi->isEmpty() && fi != (*formData).end()) {
      cout << "Value Selected: " << **fi << endl;
   }

   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

十一. 在 CGI 中使用 Cookies

HTTP 协议是一个无状态协议。但对于一个商业网站,需要在不同的页面之间维护会话信息。例如,用户注册可能需要通过多个页面才能完成。但如何在所有网页之间维护用户的会话信息呢?

在许多情况下,使用 Cookies 是记住和跟踪用户偏好、购买信息、佣金等的最有效方法,这些信息有助于提供更好的访问体验或站点统计数据。

11.1 工作原理

服务器将一些数据以 Cookie 的形式发送到访问者的浏览器。浏览器可能会接受这个 Cookie。如果接受了,它将作为一个纯文本记录存储在访问者的硬盘上。现在,当访问者访问站点上的其他页面时,可以检索该 Cookie。检索后,服务器会知道/记住之前存储的内容。

Cookies 是由五个可变长度字段组成的纯文本数据记录:

  • Expires:显示 Cookie 的过期日期。如果为空,Cookie 将在访问者退出浏览器时过期。
  • Domain:显示您网站的域名。
  • Path:显示设置 Cookie 的目录或网页的路径。如果为空,则可以从任何目录或页面检索 Cookie。
  • Secure:如果该字段包含单词 "secure",则只能通过安全服务器检索该 Cookie。如果该字段为空,则不存在此类限制。
  • Name=Value:Cookies 以键值对的形式设置和检索。

11.2 设置 Cookies

通过 HTTP 头信息设置 Cookies 非常简单。以下是一个设置 UserID 和 Password 作为 Cookie 的示例:

#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。需要注意的是,Cookies 必须在发送 Content-type:text/html\r\n\r\n 之前设置。

11.3 检索 Cookies

检索已经设置的 Cookies 非常简单。Cookies 存储在 CGI 环境变量 HTTP_COOKIE 中,格式如下:

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

以下是一个如何检索 Cookies 的示例:

#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\">";

   // 获取环境变量
   const CgiEnvironment& env = cgi.getEnvironment();

   for (cci = env.getCookieList().begin(); c

ci != env.getCookieList().end(); ++cci) {
      cout << "<tr><td>" << cci->getName() << "</td>" << endl;
      cout << "<td>" << cci->getValue() << "</td></tr>" << endl;
   }

   cout << "</table>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

此程序使用了 cgicc 库,检索所有 Cookies 并将其显示为 HTML 表格。

11.4 删除 Cookies

为了删除一个 Cookie,只需设置其到期日期为过去的日期即可。

以下是删除 Cookie 的示例代码:

#include <iostream>
using namespace std;

int main () {
   cout << "Set-Cookie:UserID=XYZ; Expires=Wed, 31-Dec-97 23:59:59 GMT;\r\n";
   cout << "Set-Cookie:Password=XYZ123; Expires=Wed, 31-Dec-97 23:59:59 GMT;\r\n";
   cout << "Content-type:text/html\r\n\r\n";

   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Delete Cookies in CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   cout << "Deleted cookies" << endl;

   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}
上一章 下一章
阅读号二维码

关注阅读号

联系二维码

联系我们

© 2024 Yoagoa. All rights reserved.

粤ICP备18007391号

站点地图