1.c++ web编程:写出你的CGI程序

2024-05-30 20:38
文章标签 c++ 程序 web 编程 cgi 写出

本文主要是介绍1.c++ web编程:写出你的CGI程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 一 什么是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 文件中的部分内容:

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

  2. AllowOverride None

  3. Options ExecCGI

  4. Order allow,deny

  5. Allow from all

  6. </Directory>

  7.  
  8. <Directory "/var/www/cgi-bin">

  9. Options All

  10. </Directory>


五 第一个CGI脚本

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

 
  1. #include <iostream>

  2. using namespace std;

  3.  
  4. int main ()

  5. {

  6.  
  7. cout << "Content-type:text/html\r\n\r\n";

  8. cout << "<html>\n";

  9. cout << "<head>\n";

  10. cout << "<title>Hello World - First CGI Program</title>\n";

  11. cout << "</head>\n";

  12. cout << "<body>\n";

  13. cout << "<h2>Hello World! This is my first CGI program</h2>\n";

  14. cout << "</body>\n";

  15. cout << "</html>\n";

  16.  
  17. return 0;

  18. }

        编译上述代码并且将二进制可执行文件命名为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报文头部都有如下格式:

 
  1. HTTP Field Name: Field Content

  2.  
  3. For Example

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


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

HeaderDescription
Content-type:A MIME string defining the format of the file being returned. Example is Content-type:text/html
Expires: DateThe 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: URLThe URL that should be returned instead of the URL requested. You can use this filed to redirect a request to any file.
Last-modified: DateThe date of last modification of the resource.
Content-length: NThe length, in bytes, of the data being returned. The browser uses this value to report the estimated download time for a file.
Set-Cookie: StringSet the cookie passed through the string

七 CGI环境变量

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

Variable NameDescription
CONTENT_TYPEThe data type of the content. Used when the client is sending attached content to the server. For example file upload etc.
CONTENT_LENGTHThe length of the query information. It's available only for POST requests
HTTP_COOKIEReturn the set cookies in the form of key & value pair.
HTTP_USER_AGENTThe User-Agent request-header field contains information about the user agent originating the request. Its name of the web browser.
PATH_INFOThe path for the CGI script.
QUERY_STRINGThe URL-encoded information that is sent with GET method request.
REMOTE_ADDRThe IP address of the remote host making the request. This can be useful for logging or for authentication purpose.
REMOTE_HOSTThe 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_METHODThe method used to make the request. The most common methods are GET and POST.
SCRIPT_FILENAMEThe full path to the CGI script.
SCRIPT_NAMEThe name of the CGI script.
SERVER_NAMEThe server's hostname or IP Address
SERVER_SOFTWAREThe name and version of the software the server is running.

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

 
  1. #include <iostream>

  2. using namespace std;

  3.  
  4. const string ENV[ 24 ] = {

  5. "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",

  6. "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING",

  7. "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION",

  8. "HTTP_HOST", "HTTP_USER_AGENT", "PATH",

  9. "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",

  10. "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME",

  11. "SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN",

  12. "SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL",

  13. "SERVER_SIGNATURE","SERVER_SOFTWARE" };

  14.  
  15. int main ()

  16. {

  17.  
  18. cout << "Content-type:text/html\r\n\r\n";

  19. cout << "<html>\n";

  20. cout << "<head>\n";

  21. cout << "<title>CGI Envrionment Variables</title>\n";

  22. cout << "</head>\n";

  23. cout << "<body>\n";

  24. cout << "<table border = \"0\" cellspacing = \"2\">";

  25.  
  26. for ( int i = 0; i < 24; i++ )

  27. {

  28. cout << "<tr><td>" << ENV[ i ] << "</td><td>";

  29. // attempt to retrieve value of environment variable

  30. char *value = getenv( ENV[ i ].c_str() );

  31. if ( value != 0 ){

  32. cout << value;

  33. }else{

  34. cout << "Environment variable does not exist.";

  35. }

  36. cout << "</td></tr>\n";

  37. }

  38. cout << "</table><\n";

  39. cout << "</body>\n";

  40. cout << "</html>\n";

  41.  
  42. return 0;

  43. }

  44.  

八 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设置脚本如下:

      

 
  1. #include <iostream>

  2. using namespace std;

  3.  
  4. int main ()

  5. {

  6.  
  7. cout << "Set-Cookie:UserID=XYZ;\r\n";

  8. cout << "Set-Cookie:Password=XYZ123;\r\n";

  9. cout << "Set-Cookie:Domain=www.tutorialspoint.com;\r\n";

  10. cout << "Set-Cookie:Path=/perl;\n";

  11. cout << "Content-type:text/html\r\n\r\n";

  12.  
  13. cout << "<html>\n";

  14. cout << "<head>\n";

  15. cout << "<title>Cookies in CGI</title>\n";

  16. cout << "</head>\n";

  17. cout << "<body>\n";

  18.  
  19. cout << "Setting cookies" << endl;

  20.  
  21. cout << "<br/>\n";

  22. cout << "</body>\n";

  23. cout << "</html>\n";

  24.  
  25. return 0;

  26. }


        从这个例子中你将了解怎么设置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代码:

 
  1. #include <iostream>

  2. #include <vector>

  3. #include <string>

  4. #include <stdio.h>

  5. #include <stdlib.h>

  6.  
  7. #include <cgicc/CgiDefs.h>

  8. #include <cgicc/Cgicc.h>

  9. #include <cgicc/HTTPHTMLHeader.h>

  10. #include <cgicc/HTMLClasses.h>

  11.  
  12. using namespace std;

  13. using namespace cgicc;

  14.  
  15. int main ()

  16. {

  17. Cgicc cgi;

  18. const_cookie_iterator cci;

  19.  
  20. cout << "Content-type:text/html\r\n\r\n";

  21. cout << "<html>\n";

  22. cout << "<head>\n";

  23. cout << "<title>Cookies in CGI</title>\n";

  24. cout << "</head>\n";

  25. cout << "<body>\n";

  26. cout << "<table border = \"0\" cellspacing = \"2\">";

  27.  
  28. // get environment variables

  29. const CgiEnvironment& env = cgi.getEnvironment();

  30.  
  31. for( cci = env.getCookieList().begin();

  32. cci != env.getCookieList().end();

  33. ++cci )

  34. {

  35. cout << "<tr><td>" << cci->getName() << "</td><td>";

  36. cout << cci->getValue();

  37. cout << "</td></tr>\n";

  38. }

  39. cout << "</table><\n";

  40.  
  41. cout << "<br/>\n";

  42. cout << "</body>\n";

  43. cout << "</html>\n";

  44.  
  45. return 0;

  46. }

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

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

这篇关于1.c++ web编程:写出你的CGI程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1016844

相关文章

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

C++的模板(八):子系统

平常所见的大部分模板代码,模板所传的参数类型,到了模板里面,或实例化为对象,或嵌入模板内部结构中,或在模板内又派生了子类。不管怎样,最终他们在模板内,直接或间接,都实例化成对象了。 但这不是唯一的用法。试想一下。如果在模板内限制调用参数类型的构造函数会发生什么?参数类的对象在模板内无法构造。他们只能从模板的成员函数传入。模板不保存这些对象或者只保存他们的指针。因为构造函数被分离,这些指针在模板外

C++工程编译链接错误汇总VisualStudio

目录 一些小的知识点 make工具 可以使用windows下的事件查看器崩溃的地方 dumpbin工具查看dll是32位还是64位的 _MSC_VER .cc 和.cpp 【VC++目录中的包含目录】 vs 【C/C++常规中的附加包含目录】——头文件所在目录如何怎么添加,添加了以后搜索头文件就会到这些个路径下搜索了 include<> 和 include"" WinMain 和

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

C/C++的编译和链接过程

目录 从源文件生成可执行文件(书中第2章) 1.Preprocessing预处理——预处理器cpp 2.Compilation编译——编译器cll ps:vs中优化选项设置 3.Assembly汇编——汇编器as ps:vs中汇编输出文件设置 4.Linking链接——链接器ld 符号 模块,库 链接过程——链接器 链接过程 1.简单链接的例子 2.链接过程 3.地址和

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C++学习 贝蒂的主页:Betty’s blog 1. 泛型编程 首先让我们来思考一个问题,如何实现一个交换函数? void swap(int& x, int& y){int tmp = x;x = y;y = tmp;} 相信大家很快就能写出上面这段代码,但是如果要求这个交换函数支持字符型

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

16.Spring前世今生与Spring编程思想

1.1.课程目标 1、通过对本章内容的学习,可以掌握Spring的基本架构及各子模块之间的依赖关系。 2、 了解Spring的发展历史,启发思维。 3、 对 Spring形成一个整体的认识,为之后的深入学习做铺垫。 4、 通过对本章内容的学习,可以了解Spring版本升级的规律,从而应用到自己的系统升级版本命名。 5、Spring编程思想总结。 1.2.内容定位 Spring使用经验