Web 編程

2018-08-12 22:03 更新

Web 編程

什么是 CGI ?

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

網(wǎng)頁瀏覽

要了解 CGI 的概念,那我們先來看看,當我們點擊超鏈接來瀏覽特定的網(wǎng)頁或 URL 時會發(fā)生什么。

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

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

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

CGI 架構(gòu)圖

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

Web 服務(wù)器配置

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

默認情況下,Apache Web 服務(wù)器配置為在/var/www/cgi-bin運行 CGI 程序。如果你想指定其他目錄運行 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ù)器,啟動并運行成功, 并且你可以運行任何其他語言(比如 Perl 或 Shell 等)所寫的 CGI 程序。

第一個 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)容。在運行 CGI 程序之前,請確保你已使用 chmod755 cplusplus.cgi UNIX 命令來改變文件的權(quán)限,使文件能夠可執(zhí)行?,F(xiàn)在,如果你點擊 cplusplus.cgi ,那么這將產(chǎn)生以下的輸出:

Hello World! This is my first CGI program

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

HTTP 報頭

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

    HTTP Field Name: Field Content

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

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

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

CGI 環(huán)境變量

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

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

這里提供一個小 CGI 程序來列出所有的 CGI 變量。點擊鏈接 Get Environment 來查看結(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 庫

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

    $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 方法

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

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

GET 方法將編碼的用戶信息附加到頁面請求后面,頁面和編碼信息用字符?分割開。如下所示:

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

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

當使用 GET 方法時,信息數(shù)據(jù)使用 HTTP 報頭 QUERY_STRING 傳遞,同時你的 CGI 程序通過訪問 QUERY_STRING 環(huán)境變量來獲取信息數(shù)據(jù)。

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

簡單的 URL 例子: GET 方法

下面是一個使用 GET 方法傳遞兩個值到 hello_get.py 程序的簡單 URL。

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

下面是一個生成 cpp_get.cgi CGI 程序的程序,它會處理來自 Web 瀏覽器的輸入。我們使用了 C++ 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>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

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

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

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

    First name: ZARA 
    Last name: ALI 

簡單的 FORM 例子: GET 方法

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

    <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 方法。它會以與 GET 方法完全相同的方式將數(shù)據(jù)信息打包,但不是將其作為在 URL 中?后面的一個文本字符串來發(fā)送,而是將它作為一個單獨的消息發(fā)送。此消息以標準輸入的形式的發(fā)送到 CGI 腳本。

同樣,利用同一個 cpp_get.cgi 程序來處理 POST 方法的輸入。我們用與上面一樣的例子,利用 HTML FORM 和提交按鈕來傳遞兩個值,但是這一次用 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 程序

當有不止一個選項需要被選擇的時候,要使用復(fù)選框。

下面是一個有兩個復(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++ 程序會產(chǎn)生 cpp_checkbox.cgi 腳本來處理由 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 程序

當僅需要選擇一個選項時,使用單選按鈕。

下面是一個有兩個單選按鈕的 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++ 程序會產(chǎn)生 cpp_checkbox.cgi 腳本來處理由 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 程序

當有多行文本需要傳遞到 CGI 程序時,要使用文本域元素。

下面是一個有文本域框的 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++ 程序會產(chǎn)生 cpp_checkbox.cgi 腳本來處理由 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 程序

當有多個可選項,但是只能選擇一個或者兩個選項時,需要使用下拉框。

下面是一個有一個下拉框的 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++ 程序會產(chǎn)生 cpp_checkbox.cgi 腳本來處理由 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é)議是一個無狀態(tài)協(xié)議。但是對于一個商業(yè)網(wǎng)站,它需要保持不同的頁面間的會話信息。例如,一個用戶的注冊需要完成許多的頁面,那么將如何保持所有網(wǎng)頁之間的用戶的會話信息將是一個問題。

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

它是如何工作的

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

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

  • Expires:cookie 將失效的日期。 如果此字段為空,那么當訪問者退出瀏覽器后 cookie 將會失效。

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

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

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

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

設(shè)置 Cookies

將 cookies 發(fā)送到瀏覽器是非常容易的。這些 cookie 會設(shè)置在 HTTP報頭的 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;
    }

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

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

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

/cgi-bin/setcookies.cgi

檢索 Cookie

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

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

下面是一個如何檢索 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

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

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

文件上傳

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

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

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

下面是一個用來處理文件上傳的腳本 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 流中寫內(nèi)容,但是你可以打開你的文件流,并將上傳文件的內(nèi)容保存到一個預(yù)定位置的文件中。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號