要了解 CGI 的概念,那我們先來(lái)看看,當(dāng)我們點(diǎn)擊超鏈接來(lái)瀏覽特定的網(wǎng)頁(yè)或 URL 時(shí)會(huì)發(fā)生什么。
然而,也可以以這樣的方式來(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ě)。
下圖簡(jiǎn)單的展示了 CGI 程序的一個(gè)簡(jiǎn)單架構(gòu):
http://wiki.jikexueyuan.com/project/cplusplus/images/cgiarch.gif" alt="" />
在你進(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 程序。
思考下面的 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)行信息的交換。
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)境變量。這些變量在編寫(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;
}
對(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)文檔。
你一定遇到過(guò)很多將信息數(shù)據(jù)從瀏覽器發(fā)送到 Web 服務(wù)器,并最終發(fā)送到 CGI 程序的情況。瀏覽器最常使用 GET 和 POST 兩種方法將信息傳送給 Web 服務(wù)器。
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)傳遞信息。
下面是一個(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
下面是一個(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>
將信息數(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>
當(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;
}
當(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;
}
當(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;
}
當(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;
}
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ù)器檢索到。如果該字段為空,將不存在這樣的限制。
將 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
檢索所有設(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ù)定位置的文件中。