在线二区人妖系列_国产亚洲欧美日韩在线一区_国产一级婬片视频免费看_精品少妇一区二区三区在线

鍍金池/ 教程/ C/ Web 編程
動(dòng)態(tài)內(nèi)存
類(lèi)和對(duì)象
接口 (抽象類(lèi))
結(jié)構(gòu)體
循環(huán)的類(lèi)型
函數(shù)
數(shù)字
日期和時(shí)間
基本語(yǔ)法
多態(tài)
數(shù)據(jù)抽象
注釋
命名空間
字符串
預(yù)處理器
決策語(yǔ)句
修飾符的類(lèi)型
鍙橀噺綾誨瀷
基本輸入輸出
操作符
數(shù)組
模板
多線程
繼承
Web 編程
信號(hào)處理
指針
存儲(chǔ)類(lèi)型
概述
引用
常量
異常處理
開(kāi)發(fā)環(huán)境
重載
變量作用域
數(shù)據(jù)類(lèi)型
數(shù)據(jù)封裝
文件和流

Web 編程

什么是 CGI ?

  • 通用網(wǎng)關(guān)接口(Common Gateway Interface),簡(jiǎn)稱(chēng) CGI,是一組定義如何將信息在 Web 服務(wù)器和一個(gè)自定義腳本之間交換的標(biāo)準(zhǔn)。
  • 目前 CGI 的規(guī)范是由 NCSA 維護(hù)的;NCSA 定義 CGI 如下:
  • 通用網(wǎng)關(guān)接口(CGI),是外部網(wǎng)關(guān)程序與信息服務(wù)器(例如,HTTP 服務(wù)器)之間的接口標(biāo)準(zhǔn)。
  • 目前應(yīng)用的版本是 CGI /1.1;CGI/1.2 版本正在開(kāi)發(fā)中。

網(wǎng)頁(yè)瀏覽

要了解 CGI 的概念,那我們先來(lái)看看,當(dāng)我們點(diǎn)擊超鏈接來(lái)瀏覽特定的網(wǎng)頁(yè)或 URL 時(shí)會(huì)發(fā)生什么。

  • 您的瀏覽器連接到 HTTP Web 服務(wù)器,并且請(qǐng)求 URL ,文件名。
  • Web 服務(wù)器將會(huì)解析 URL,并且會(huì)查找文件名。如果找到所請(qǐng)求的文件,那么 Web 服務(wù)器會(huì)將該文件發(fā)送給瀏覽器,否則它會(huì)發(fā)送一個(gè)錯(cuò)誤信息表明您請(qǐng)求了一個(gè)錯(cuò)誤的文件。
  • Web 瀏覽器的響應(yīng)來(lái)自于 Web 服務(wù)器,并且瀏覽器要顯示所接收到的文件或者錯(cuò)誤消息的響應(yīng)。

然而,也可以以這樣的方式來(lái)設(shè)置 HTTP 服務(wù)器:每當(dāng)在某個(gè)目錄中的文件被請(qǐng)求時(shí),該文件并不被發(fā)送回;代替的是,這個(gè)請(qǐng)求作為一個(gè)程序來(lái)被執(zhí)行,由該程序產(chǎn)生輸出,并被發(fā)送回給瀏覽器來(lái)顯示。

公共網(wǎng)關(guān)接口(CGI)是一個(gè)能使應(yīng)用程序(稱(chēng)為 CGI 程序或 CGI 腳本)與 Web 服務(wù)器和客戶端進(jìn)行交互的標(biāo)準(zhǔn)協(xié)議。這些 CGI 程序可以使用 Python,Perl,Shell,C 或 C++ 等語(yǔ)言來(lái)編寫(xiě)。

CGI 架構(gòu)圖

下圖簡(jiǎn)單的展示了 CGI 程序的一個(gè)簡(jiǎn)單架構(gòu):

http://wiki.jikexueyuan.com/project/cplusplus/images/cgiarch.gif" alt="" />

Web 服務(wù)器配置

在你進(jìn)行 CGI 編程之前確保您的 Web 服務(wù)器支持 CGI,并且它被配置為能夠處理 CGI 程序。 HTTP 服務(wù)器執(zhí)行的所有 CGI 程序被保存在一個(gè)預(yù)先配置的目錄里。這個(gè)目錄稱(chēng)為 CGI 目錄,一般其命名為 /var/www/cgi-bin。盡管 CGI 文件是 C++ 可執(zhí)行的,但是按照慣例他們會(huì)有擴(kuò)展名 .cgi.

默認(rèn)情況下,Apache Web 服務(wù)器配置為在/var/www/cgi-bin運(yùn)行 CGI 程序。如果你想指定其他目錄運(yùn)行 CGI 腳本,你可以在 httpd.conf 配置文件中修改下面部分的內(nèi)容:

    <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 服務(wù)器,啟動(dòng)并運(yùn)行成功, 并且你可以運(yùn)行任何其他語(yǔ)言(比如 Perl 或 Shell 等)所寫(xiě)的 CGI 程序。

第一個(gè) CGI 程序

思考下面的 C++ 程序內(nèi)容:

    #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;
    }

編譯上面的代碼,并命名可執(zhí)行文件為 cplusplus.cgi. 該文件被保存在/var/WWW/cgi-bin目錄里,并且它有上面的內(nèi)容。在運(yùn)行 CGI 程序之前,請(qǐng)確保你已使用 chmod755 cplusplus.cgi UNIX 命令來(lái)改變文件的權(quán)限,使文件能夠可執(zhí)行?,F(xiàn)在,如果你點(diǎn)擊 cplusplus.cgi ,那么這將產(chǎn)生以下的輸出:

Hello World! This is my first CGI program

以上的 C++ 程序是一個(gè)簡(jiǎn)單的將輸出寫(xiě)入 STDOUT 文件(即屏幕)的程序。它有一個(gè)可用的重要和額外的功能是,第一行要輸出 Content-type:text/html\r\n\r\n. 這一行被發(fā)送回瀏覽器,并指定在瀏覽器屏幕上顯示出來(lái)的內(nèi)容類(lèi)型。 現(xiàn)在,你理解了 CGI 的基本概念,然后你就可以使用 Python 寫(xiě)許多復(fù)雜的 CGI 程序。一個(gè) C++ 的 CGI 程序可以與任何其他外部系統(tǒng)(例如 RDBMS )交互,從而來(lái)進(jìn)行信息的交換。

HTTP 報(bào)頭

Content-type:text/html\r\n\r\n 是發(fā)送到瀏覽器的 HTTP 報(bào)頭的一部分,它用來(lái)幫助瀏覽器解析文本內(nèi)容。下面的表格展示了 HTTP 報(bào)頭

    HTTP Field Name: Field Content

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

還有其他一些你可能經(jīng)常會(huì)在 CGI 編程中使用的重要HTTP報(bào)頭。

報(bào)頭 描述
Content-type: 一個(gè)MIME字符串格式的文件會(huì)被返回。例如:Content-type:text/htm
Expires: Date Date:頁(yè)面信息失效的日期。這運(yùn)行在瀏覽器端,由瀏覽器決定何時(shí)需要刷新頁(yè)面。一個(gè)有效的日期字符串格式應(yīng)該是這樣的: 01 Jan 1998 12:00:00 GMT.
Location: URL 這里的 URL 是應(yīng)當(dāng)返回的 URL,而不是請(qǐng)求的 URL.你可以使用此來(lái)重定向一個(gè)請(qǐng)求到任何文件。
Last-modified: Date 資源最近修改的日期。
Content-length: N 返回?cái)?shù)據(jù)的長(zhǎng)度,以字節(jié)為單位存儲(chǔ)。瀏覽器使用這個(gè)值來(lái)預(yù)估計(jì)文件的下載時(shí)間。
Set-Cookie: String 通過(guò)字符串 string 設(shè)置 cookie

CGI 環(huán)境變量

所有 CGI 程序可使用下列環(huán)境變量。這些變量在編寫(xiě) CGI 程序時(shí),發(fā)揮著重要的作用。

變量名 描述
CONTENT_TYPE 內(nèi)容的數(shù)據(jù)類(lèi)型。當(dāng)客戶端發(fā)送連接內(nèi)容到服務(wù)器時(shí)使用。例如文件上傳等。
CONTENT_LENGTH 查詢信息的長(zhǎng)度。它僅適用于 POST 請(qǐng)求。
HTTP_COOKIE 以鍵值對(duì)的形式返回設(shè)置的 cookies 。
HTTP_USER_AGENT 用戶代理請(qǐng)求頭字段包含發(fā)起請(qǐng)求的用戶代理的有關(guān)信息,包括 Web 瀏覽器的名稱(chēng)。
PATH_INFO CGI 腳本的路徑信息。
QUERY_STRING 與發(fā)送 GET 請(qǐng)求一同發(fā)送的 URL 編碼信息。
REMOTE_ADDR 發(fā)出請(qǐng)求的遠(yuǎn)程主機(jī)的 IP 地址。這可用于記錄日志或認(rèn)證。
REMOTE_HOST 發(fā)出請(qǐng)求的主機(jī)的完全資格名稱(chēng)。如果該信息不可用,則REMOTE_ADDR 可用于獲取 IR 地址。
REQUEST_METHOD 用于請(qǐng)求的方法。最常用的方法是 GET 和 POST.
SCRIPT_FILENAME CGI 腳本的完全路徑。
SCRIPT_NAME CGI 腳本的名稱(chēng)。
SERVER_NAME 服務(wù)器的主機(jī)名或是 IP 地址。
SERVER_SOFTWARE 服務(wù)器正在運(yùn)行軟件的名稱(chēng)和版本。

這里提供一個(gè)小 CGI 程序來(lái)列出所有的 CGI 變量。點(diǎn)擊鏈接 Get Environment 來(lái)查看結(jié)果。

    #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 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 庫(kù)

對(duì)于真正的應(yīng)用來(lái)說(shuō),你需要你的CGI程序來(lái)完成許多操作。現(xiàn)在有一個(gè)用 C++ 編寫(xiě)的 CGI 程序庫(kù),你可以從 ftp://ftp.gnu.org/gnu/cgicc/ 下載并按照以下步驟來(lái)安裝此庫(kù):

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

你可以在 C++ CGI Lib Documentation 上查看相關(guān)文檔。

GET 和 POST 方法

你一定遇到過(guò)很多將信息數(shù)據(jù)從瀏覽器發(fā)送到 Web 服務(wù)器,并最終發(fā)送到 CGI 程序的情況。瀏覽器最常使用 GET 和 POST 兩種方法將信息傳送給 Web 服務(wù)器。

利用 GET 方法傳遞數(shù)據(jù)

GET 方法將編碼的用戶信息附加到頁(yè)面請(qǐng)求后面,頁(yè)面和編碼信息用字符?分割開(kāi)。如下所示:

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

GET 方法是將信息數(shù)據(jù)從瀏覽器傳遞到 Web 服務(wù)器的默認(rèn)方法。在瀏覽器的地址欄里面,此方法會(huì)產(chǎn)生一個(gè)長(zhǎng)長(zhǎng)的字符串。如果你有密碼或其他敏感信息要傳遞給服務(wù)器,千萬(wàn)不要使用 GET 方法。 GET 方法有大小限制,在請(qǐng)求字符串里面,最多可以有 1024 個(gè)字符。

當(dāng)使用 GET 方法時(shí),信息數(shù)據(jù)使用 HTTP 報(bào)頭 QUERY_STRING 傳遞,同時(shí)你的 CGI 程序通過(guò)訪問(wèn) QUERY_STRING 環(huán)境變量來(lái)獲取信息數(shù)據(jù)。

你可以通過(guò)簡(jiǎn)單地串聯(lián)鍵值對(duì)和任何 URL 來(lái)傳遞信息數(shù)據(jù),或者可以使用HTML<FORM>標(biāo)簽,通過(guò)利用 GET 方法來(lái)傳遞信息。

簡(jiǎn)單的 URL 例子: GET 方法

下面是一個(gè)使用 GET 方法傳遞兩個(gè)值到 hello_get.py 程序的簡(jiǎn)單 URL。

/cgi-bin/cpp_get.cgi?first_name=ZARA&last_name=ALI

下面是一個(gè)生成 cpp_get.cgi CGI 程序的程序,它會(huì)處理來(lái)自 Web 瀏覽器的輸入。我們使用了 C++ CGI 庫(kù),這使得它非常容易訪問(wèn)傳遞的信息:

    #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>Using GET and POST Methods</title>\n";
       cout << "</head>\n";
       cout << "<body>\n";

       form_iterator fi = formData.getElement("first_name");  
       if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "First name: " << **fi << endl;  
       }else{
      cout << "No text entered for first name" << endl;  
       }
       cout << "<br/>\n";
       fi = formData.getElement("last_name");  
       if( !fi->isEmpty() &&fi != (*formData).end()) {  
      cout << "Last name: " << **fi << endl;  
       }else{
      cout << "No text entered for last name" << endl;  
       }
       cout << "<br/>\n";

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

       return 0;
    }

現(xiàn)在,編譯上面的程序,如下所示:

    $g++ -o cpp_get.cgi cpp_get.cpp -lcgicc

它將會(huì)產(chǎn)生 cpp_get.cgi,并把它放在你的 CGI 目錄,并嘗試使用下面的鏈接訪問(wèn):

/cgi-bin/cpp_get.cgi?first_name=ZARA&last_name=ALI

這將會(huì)產(chǎn)生如下的結(jié)果:

    First name: ZARA 
    Last name: ALI 

簡(jiǎn)單的 FORM 例子: GET 方法

下面是一個(gè)使用 HTML FORM 和提交按鈕來(lái)傳遞兩個(gè)值的簡(jiǎn)單例子。我們將使用同一個(gè) CGI 腳本 cpp_get.cgi 來(lái)處理此輸入。

    <form action="/cgi-bin/cpp_get.cgi" method="get">
    First Name: <input type="text" name="first_name">  <br />

    Last Name: <input type="text" name="last_name" />
    <input type="submit" value="Submit" />
    </form>

利用 POST 方法傳遞數(shù)據(jù)

將信息數(shù)據(jù)傳遞給 CGI 程序,一般比較可靠的方法是 POST 方法。它會(huì)以與 GET 方法完全相同的方式將數(shù)據(jù)信息打包,但不是將其作為在 URL 中?后面的一個(gè)文本字符串來(lái)發(fā)送,而是將它作為一個(gè)單獨(dú)的消息發(fā)送。此消息以標(biāo)準(zhǔn)輸入的形式的發(fā)送到 CGI 腳本。

同樣,利用同一個(gè) cpp_get.cgi 程序來(lái)處理 POST 方法的輸入。我們用與上面一樣的例子,利用 HTML FORM 和提交按鈕來(lái)傳遞兩個(gè)值,但是這一次用 POST 方法,如下所示:

    <form action="/cgi-bin/cpp_get.cgi" method="post">
    First Name: <input type="text" name="first_name"><br />
    Last Name: <input type="text" name="last_name" />

    <input type="submit" value="Submit" />
    </form>

傳遞復(fù)選框數(shù)據(jù)到 CGI 程序

當(dāng)有不止一個(gè)選項(xiàng)需要被選擇的時(shí)候,要使用復(fù)選框。

下面是一個(gè)有兩個(gè)復(fù)選框的 HTML 表單樣例代碼。

    <form action="/cgi-bin/cpp_checkbox.cgi" 
     method="POST" 
     target="_blank">
    <input type="checkbox" name="maths" value="on" /> Maths
    <input type="checkbox" name="physics" value="on" /> Physics
    <input type="submit" value="Select Subject" />
    </form>

下面 C++ 程序會(huì)產(chǎn)生 cpp_checkbox.cgi 腳本來(lái)處理由 Web 瀏覽器提供的復(fù)選框按鈕的輸入。

    #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;
       bool maths_flag, physics_flag;

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

       maths_flag = formData.queryCheckbox("maths");
       if( maths_flag ) {  
      cout << "Maths Flag: ON " << endl;  
       }else{
      cout << "Maths Flag: OFF " << endl;  
       }
       cout << "<br/>\n";

       physics_flag = formData.queryCheckbox("physics");
       if( physics_flag ) {  
      cout << "Physics Flag: ON " << endl;  
       }else{
      cout << "Physics Flag: OFF " << endl;  
       }
       cout << "<br/>\n";
       cout << "</body>\n";
       cout << "</html>\n";

       return 0;
    }

傳遞單選按鈕數(shù)據(jù)到 CGI 程序

當(dāng)僅需要選擇一個(gè)選項(xiàng)時(shí),使用單選按鈕。

下面是一個(gè)有兩個(gè)單選按鈕的 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>

下面的 C++ 程序會(huì)產(chǎn)生 cpp_checkbox.cgi 腳本來(lái)處理由 Web 瀏覽器提供的單選按鈕的輸入。

    #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;
    }

傳遞文本域數(shù)據(jù)到 CGI 程序

當(dāng)有多行文本需要傳遞到 CGI 程序時(shí),要使用文本域元素。

下面是一個(gè)有文本域框的 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>

下面的 C++ 程序會(huì)產(chǎn)生 cpp_checkbox.cgi 腳本來(lái)處理由 Web 瀏覽器提供的文本域的輸入。

    #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;
    }

傳遞下拉框數(shù)據(jù)到 CGI 程序

當(dāng)有多個(gè)可選項(xiàng),但是只能選擇一個(gè)或者兩個(gè)選項(xiàng)時(shí),需要使用下拉框。

下面是一個(gè)有一個(gè)下拉框的 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>

下面的 C++ 程序會(huì)產(chǎn)生 cpp_checkbox.cgi 腳本來(lái)處理由 Web 瀏覽器提供的下拉框的輸入。

    #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 協(xié)議是一個(gè)無(wú)狀態(tài)協(xié)議。但是對(duì)于一個(gè)商業(yè)網(wǎng)站,它需要保持不同的頁(yè)面間的會(huì)話信息。例如,一個(gè)用戶的注冊(cè)需要完成許多的頁(yè)面,那么將如何保持所有網(wǎng)頁(yè)之間的用戶的會(huì)話信息將是一個(gè)問(wèn)題。

在許多情況下,使用 cookies 是記錄和跟蹤,喜好,所購(gòu)物品,傭金或其他能提供更好訪問(wèn)體驗(yàn)的信息或是網(wǎng)站的統(tǒng)計(jì)數(shù)據(jù)的最有效的方法。

它是如何工作的

你的服務(wù)器發(fā)送一些 cookie 格式的數(shù)據(jù)給訪問(wèn)者的瀏覽器。該瀏覽器可能接受了該 cookie. 如果是這樣,它以純文本的方式記錄在訪問(wèn)者的硬盤(pán)驅(qū)動(dòng)器上?,F(xiàn)在,當(dāng)訪問(wèn)者訪問(wèn)你的網(wǎng)站上的其他頁(yè)面時(shí),該 cookie 可用于檢索。一旦檢索到,你的服務(wù)器就會(huì)知道/記起已存儲(chǔ)的信息。

Cookies 是一個(gè)記錄了5可變長(zhǎng)度字段的純文本數(shù)據(jù):

  • Expires:cookie 將失效的日期。 如果此字段為空,那么當(dāng)訪問(wèn)者退出瀏覽器后 cookie 將會(huì)失效。

  • Domain :網(wǎng)站的域名。

  • Path :設(shè)置 cookie 的目錄或網(wǎng)頁(yè)的路徑。如果你想要從任何目錄或頁(yè)面檢索 cookie ,此字段將設(shè)置為空。

  • Secure :如果該字段包含單詞 "secure",那么該 cookie 僅可由一個(gè)安全的服務(wù)器檢索到。如果該字段為空,將不存在這樣的限制。

  • Name=Value:cookie 將以鍵值對(duì)的形式設(shè)置和檢索。

設(shè)置 Cookies

將 cookies 發(fā)送到瀏覽器是非常容易的。這些 cookie 會(huì)設(shè)置在 HTTP報(bào)頭的 Content-type 字段之前,并與其一起發(fā)送出去。假設(shè)你要將 UserID 和 Password 設(shè)置為 cookie. cookie 的設(shè)置如下所示

    #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;
    }

從這個(gè)例子中,你一定要了解如何設(shè)置 cookie。 我們使用 HTTP 報(bào)頭的 Set-Cookie 字段設(shè)置 cookie。

cookies 的屬性,如 Expires, Domain 和 Path 是可選設(shè)置項(xiàng)。值得注意的是,cookies 設(shè)置在魔力代碼行 Content-type:text/html\r\n\r\n 之前。

編譯上面的程序?qū)a(chǎn)生 setcookies.cgi,并嘗試使用下面的鏈接來(lái)設(shè)置 cookie。它會(huì)在你的電腦上設(shè)置四個(gè) cookie:

/cgi-bin/setcookies.cgi

檢索 Cookie

檢索所有設(shè)置的 cookie 是非常容易的。 cookie 存儲(chǔ)在 CGI 環(huán)境變量的 HTTP_COOKIE 字段,它們的形式如下所示:

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

下面是一個(gè)如何檢索 cookie 的例子。

    #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;
    }

現(xiàn)在,編譯上面的程序?qū)a(chǎn)生 getcookies.cgi,并且試圖列出你電腦上所有可用的 cookies:

/cgi-bin/getcookies.cgi

這將會(huì)列出在上一節(jié)設(shè)置的四個(gè) cookies 和其它你電腦上設(shè)置的 cookies。

    UserID XYZ 
    Password XYZ123 
    Domain www.tutorialspoint.com 
    Path /perl

文件上傳

要上傳一個(gè)文件,HTML 表單必須將 enctype 屬性設(shè)置為 multipart/form-data。 type 為 file 的 input 標(biāo)簽將會(huì)產(chǎn)生一個(gè)“選擇文件”按鈕。

    <html>
    <body>
       <form enctype="multipart/form-data" 
    action="/cgi-bin/cpp_uploadfile.cgi" 
    method="post">
       <p>File: <input type="file" name="userfile" /></p>
       <p><input type="submit" value="Upload" /></p>
       </form>
    </body>
    </html>

注意:對(duì)上面的例子,我們已經(jīng)禁止了向我們的服務(wù)器上傳文件。但是你可以在你自己的服務(wù)上實(shí)驗(yàn)以上的代碼。

下面是一個(gè)用來(lái)處理文件上傳的腳本 cpp_uploadfile.cpp

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

       cout << "Content-type:text/html\r\n\r\n";
       cout << "<html>\n";
       cout << "<head>\n";
       cout << "<title>File Upload in CGI</title>\n";
       cout << "</head>\n";
       cout << "<body>\n";

       // get list of files to be uploaded
       const_file_iterator file = cgi.getFile("userfile");
       if(file != cgi.getFiles().end()) {
      // send data type at cout.
      cout << HTTPContentHeader(file->getDataType());
      // write content at cout.
      file->writeToStream(cout);
       }
       cout << "<File uploaded successfully>\n";
       cout << "</body>\n";
       cout << "</html>\n";

       return 0;
    }

上面的例子是在 cout 流中寫(xiě)內(nèi)容,但是你可以打開(kāi)你的文件流,并將上傳文件的內(nèi)容保存到一個(gè)預(yù)定位置的文件中。

上一篇:變量作用域下一篇:常量