cgi(common gateway inte***ce: 公用閘道器介面)規定了web伺服器呼叫其他可執行程式(cgi程式)的介面協議標準。web伺服器通過呼叫cgi程式實現和web瀏覽器的互動,也就是cgi程式接受web瀏覽器傳送給web伺服器的資訊,進行處理,將響應結果再回送給web伺服器及web瀏覽器。cgi程式一般完成web網頁中表單(form)資料的處理、資料庫查詢和實現與傳統應用系統的整合等工作。cgi程式可以用任何程式語言編寫,如shell指令碼語言、perl、fortran、pascal、c語言等。但是用c語言編寫的cgi程式具有執行速度快、安全性高(因為c語言程式是編譯執行且不可被修改)等特點。
cgi介面標準包括標準輸入、環境變數、標準輸出三部分。
1.標準輸入
cgi程式像其他可執行程式一樣,可通過標準輸入(stdin)從web伺服器得到輸入資訊,如form中的資料,這就是所謂的向cgi程式傳遞資料的post方法。這意味著在作業系統命令列狀態可執行cgi程式,對cgi程式進行除錯。post方法是常用的方法,本文將以此方法為例,分析cgi程式設計的方法、過程和技巧。
2.環境變數
作業系統提供了許多環境變數,它們定義了程式的執行環境,應用程式可以訪問它們。web伺服器和cgi介面又另外設定了自己的一些環境變數,用來向cgi程式傳遞一些重要的引數。cgi的get方法還通過環境變數query-string向cgi程式傳遞form中的資料。
3.標準輸出
cgi程式通過標準輸出(stdout)將輸出資訊傳送給web伺服器。傳送給web伺服器的資訊可以用各種格式,通常是以純文字或者html文字的形式,這樣我們就可以在命令列狀態除錯cgi程式,並且得到它們的輸出。
下面是乙個簡單的cgi程式,它將html中form的資訊直接輸出到web瀏覽器。
# include
# include
main()
下面對此程式作一下簡要的分析。
printf (″content type :text/plain\n\n″);
此行通過標準輸出將字串″content type :text/plain\n\n″傳送給web伺服器。它是乙個mime頭資訊,它告訴web伺服器隨後的輸出是以純ascii文字的形式。請注意在這個頭資訊中有兩個新行符,這是因為web伺服器需要在實際的文字資訊開始之前先看見乙個空行。
if (getenv(″content-length″))
n=atoi (getenv(″content-length″));
此行首先檢查環境變數content-length是否存在。web伺服器在呼叫使用post方法的cgi程式時設定此環境變數,它的文字值表示web伺服器傳送給cgi程式的輸入中的字元數目,因此我們使用函式atoi() 將此環境變數的值轉換成整數,並賦給變數n。請注意web伺服器並不以檔案結束符來終止它的輸出,所以如果不檢查環境變數content-length,cgi程式就無法知道什麼時候輸入結束了。
for (i=0;i
i++)
putchar(getchar());
此行從0迴圈到(content-length-1)次將標準輸入中讀到的每乙個字元直接拷貝到標準輸出,也就是將所有的輸入以ascii的形式回送給web伺服器。
通過此例,我們可將cgi程式的一般工作過程總結為如下幾點。
1.通過檢查環境變數content-length,確定有多少輸入;
2.迴圈使用getchar()或者其他檔案讀函式得到所有的輸入;
3.以相應的方法處理輸入;
4.通過″contenttype:″頭資訊,將輸出資訊的格式告訴web伺服器;
5.通過使用printf()或者putchar()或者其他的檔案寫函式,將輸出傳送給web伺服器。
總之,cgi程式的主要任務就是從web伺服器得到輸入資訊,進行處理,然後將輸出結果再送回給web伺服器。
環境變數是文字串(名字/值對),可以被os shell或其他程式設定 ,也可以被其他程式訪問。它們是web伺服器傳遞資料給cgi程式的簡單手段,之所以稱為環境變數是因為它們是全域性變數,任何程式都可以訪問它們。
下面是cgi程式設計中常常要用到的一些環境變數。
http-referer:呼叫該cgi程式的網頁的url。
remote-host:呼叫該cgi程式的web瀏覽器的機器名和網域名稱。
request-method:指的是當web伺服器傳遞資料給cgi程式時所採用的方法,分為get和post兩種方法。get方法僅通過環境變數(如query-string)傳遞資料給cgi程式,而post方法通過環境變數和標準輸入傳遞資料給cgi程式,因此post方法可較方便地傳遞較多的資料給cgi程式。
if (getenv (″content-length″))
n=atoi(getenv (″content-length″));
請注意程式中最好呼叫兩次getenv():第一次檢查是否存在該環境變數,第二次再使用該環境變數。這是因為函式getenv()在給定的環境變數名不存在時,返回乙個null(空)指標,如果你不首先檢查而直接引用它,當該環境變數不存在時會引起cgi程式崩潰。
1.分析名字/值對
當使用者提交乙個html form時,web瀏覽器首先對form中的資料以名字/值對的形式進行編碼,並傳送給web伺服器,然後由web伺服器傳遞給cgi程式。其格式如下:
name1=value1&name2=value2&name3=value3&name4=value4&...
其中名字是form中定義的input、select或textarea等標置(tag)名字,值是使用者輸入或選擇的標置值。這種格式即為url編碼,程式中需要對其進行分析和解碼。要分析這種資料流,cgi程式必須首先將資料流分解成一組組的名字/值對。這可以通過在輸入流中查詢下面的兩個字元來完成。
每當找到字元=,標誌著乙個form變數名字的結束;每當找到字元& ,標誌著乙個form變數值的結束。請注意輸入資料的最後乙個變數的值不以&結束。
一旦名字/值對分解後,還必須將輸入中的一些特殊字元轉換成相應的ascii字元。這些特殊字元是:
+:將+轉換成空格符;
%xx:用其十六進製制ascii碼值表示的特殊字元。根據值xx將其轉換成相應的ascii字元。
對form變數名和變數值都要進行這種轉換。下面是乙個對form資料進行分析並將結果回送給web伺服器的cgi程式。
#include
#include
#include
int htoi(char *);
main()
break;
case ′=′:
c=′:′;
is-eq=1;
break;
}; putchar(c);
if (is-eq) putchar(′ ′);
} putchar (′\n′);
fflush(stdout);
} /* convert hex string to int */
int htoi(char *s)
上面的程式首先輸出乙個mime頭資訊給web伺服器,檢查輸入中的字元數,並迴圈檢查每乙個字元。當發現字元為&時,意味著乙個名字/值對的結束,程式輸出乙個空行;當發現字元為+時,將它轉換成空格; 當發現字元為%時,意味著乙個兩字元的十六進製制值的開始,呼叫htoi()函式將隨後的兩個字元轉換為相應的ascii字元;當發現字元為=時,意味著乙個名字/值對的名字部分的結束,並將它轉換成字元:。最後將轉換後的字元輸出給web伺服器。
cgi程式產生的輸出由兩部分組成:mime頭資訊和實際的資訊。兩部分之間以乙個空行分開。我們已經看到怎樣使用mime頭資訊″content type :text/plain\n\n″和printf()、put char()等函式呼叫來輸 出純ascii文字給web伺服器。實際上,我們也可以使用mime頭資訊″content type :text/html\n\n″來輸出html源**給web伺服器。請注意任何mime頭資訊後必須有乙個空行。一旦傳送這個mime頭資訊給we b伺服器後,web瀏覽器將認為隨後的文字輸出為html源**,在html源**中可以使用任何html結構,如超鏈、影象、form,及對其他cgi程 序的呼叫。也就是說,我們可以在cgi程式中動態產生html源**輸出 ,下面是乙個簡單的例子。
#include
#include
main()
上面的cgi程式簡單地用printf()函式來產生html源**。請注意在輸出的字串中如果有雙引號,在其前面必須有乙個後斜字元, 這是因為整個html**串已經在雙引號內,所以html**串中的雙引號符必須用乙個後斜字元\來轉義。
本文詳細分析了用c語言進行cgi程式設計的方法、過程和技巧。c語言的cgi程式雖然執行速度快、可靠性高,但是相對於perl語言來說,c語言缺乏強有力的字串處理能力,因此在實際應用中,應根據需 要和個人愛好來選擇合適的cgi程式語言。
用c寫CGI 程式簡要指南
將 轉換成空格符 xx 用其十六進製制ascii碼值表示的特殊字元。根據值xx將其轉換成相應的ascii字元。對form變數名和變數值都要進行這種轉換。下面是乙個對form資料進行分析並將結果回送給web伺服器的cgi程式。include include include int htoi char ...
C語言寫cgi,個人的cgi庫
cgi程式可以用c c perl等多種語言編寫。本文以乙個最簡單的表單提交和cgi處理為例,示範了如何使用c語言編寫處理表單的cgi程式,這裡的有本人寫的乙個很小的cgi庫 一些相關的函式。更多關於cgi的背景知識,網上有很多介紹。表單頁面 如下 自製的cgi庫cgilib的標頭檔案 ifndef ...
D 語言編寫CGI程式
編寫main.d,內容如下 import arsd.cgi void yourfunction cgi cgi mixin genericmain yourfunction 用命令編譯程式,得到可執行程式main dmd main.d cgi.d 直接執行main,可以看到輸出的是http響應。ca...