CGI 是 Common Gateway Interface 的意思, 它是一個從瀏覽器利用 URL 傳喚伺服機去啟動一個執行檔案, 並且將執行結果傳回瀏覽器的標準介面。
CGI 涉及伺服機或整個網站的安全性。 所以,每一個網頁伺服機關於 CGI 的支援程度或設定規則,不盡相同。 此處以中央大學數學系的設定為例。 |
只要放在您的 WEBHOME 資料夾內就可以了。
但是 CGI 程式本身,和它所在的資料夾,其檔案模式都不可以是 world writable。
如果對於網頁伺服機的相關術語還有疑問,您應該回頭參考 HTML 自修第三課。 如果對於 UNIX 檔案模式還有疑問,應該回頭參考 UNIX 自修教材。 |
任何可以在網頁伺服機的作業系統中執行的程式都行,但是檔案名必須是 *.cgi 的形式。 如果是腳本程式,則必須知道在伺服機上的解譯程式是否存在, 以及它所在的位置。 例如
目前的網頁伺服機作業系統是 Solaris 2.6。 所以如果要製作一個本身可執行的程式出來當做 CGI 程式, 則此程式之原始碼必須在 Solaris 2.6 作業系統中編譯才行。 例如,我們可以用 C 語言寫一個簡單的 CGI 程式: test_cgi.c, 在一台作業系統為 Solaris 2.6 的工作站 (例如姜夔、王維) 上編譯:
gcc -o test_c.cgi test_cgi.c得到結果
http://www.math.ncu.edu.tw/mcl/bcc16/B/html/test_c.cgi
http://www.math.ncu.edu.tw/mcl/bcc16/B/html/uid.cgi則此程式的檔案模式必須是域內 (world) 可執行, 例如 755,則是以網頁伺服機的身份來執行,也就是 httpd。 因此,當它執行的時候,如果需要用到其他的電腦資源, 例如要從其他檔案讀、寫資料,則都是以 httpd 的身份去讀、寫。 在以上例子,應該得到 http。
http://www.math.ncu.edu.tw/~shann/bcc16/B/html/uid.cgi而且程式檔案所屬的用戶與群組編號符合:UID >= 100 且 GID >= 80, 則此程式的檔案模式只要是用戶 (user) 可執行, 例如 700 或 500 或 744 或 755 都可以, 就會以用戶的身份來執行。例如上述的 uid.cgi 是一個 C-Shell 腳本, 它的檔案模式是 755,屬於 shann 用戶,所以就是以 shann 的身份來執行。 在以上例子,應該得到 shann。
只要輸出到 stdout 的資料,就會被轉送給網頁伺服軟體。 因此,輸出必須是純文字資料,而且第一列必須是
Content-type:text/html第二列必須是一個空列。這兩列資料是送去給網頁伺服軟體作辨別用的。
從第三列開始,就是一個正常的 HTML 文件該有的文字。
HTML 提供一些機制 (包括 FORM 和 ISINDEX),使得使用者可以從網頁上輸入資料。 而這些資料就會回傳到網頁伺服機。 如果伺服機發現這個 URL 是要透過 CGI 介面啟動一個執行檔案 (由 URL 裡面的資料夾名稱、或是檔案的副檔名來判斷), 就會透過 CGI 介面啟動可執行檔, 並將網頁傳回的資料以某種形式傳送給執行檔。
將資料回傳伺服機的方法,分成 GET 和 POST 兩種。 資料本身的類型,分成 ISINDEX 和 FORM 兩種。
最簡單的狀況,是以 GET 方法回傳 ISINDEX 資料。
就直接寫在 URL 裡面,以一個問號 ? 隔開網址和回傳資料。
整個 URL 必須符合 URL 的編碼標準,例如空格編成 +,
而 + 自己編成 %2B。
如果對於 URL 編碼規則還有疑問,應該回頭參考 HTML 自修教材第三課。 |
http://www.math.ncu.edu.tw/mcl/bcc16/B/html/get.cgi?Hello+worldCGI 介面將會執行 get.cgi,將 ? 以後的所有字串, 當做線上參數 (command line arguments) 提供給程式。也就是說,就好像在 UNIX 文字介面上執行
get.cgi Hello world一樣。有一些會讓 UNIX 的文字介面產生特殊動作的字元, 例如 &,會被 CGI 改成 \&。 讀者可以嘗試自己將上述 URL 輸入在瀏覽器的網址方格內, 並且多做些實驗。而 get.cgi 將會回應它所收到的的參數是什麼。
HTML 的 ISINDEX 標籤照規定應該用在 HEAD 環境內。 但是許多人認為寫在 BODY 環境內比較方便,所以瀏覽器通常會接受 (至少 IE 和 Netscape 都會接受)。 ISINDEX 會在瀏覽器中產生一個輸入格, 讓人打字輸入資料,按 Enter 之後,輸入的資料會以 GET 方式回傳到同一張網頁 (通常是一個 CGI 程式)。
http://www.math.ncu.edu.tw/mcl/bcc16/B/html/isindex.cgi?1%2B1+%3D+2而 isindex.cgi 則回應它收到的線上參數。
如果伺服機看到 URL 包含 CGI 程式和回傳資料, 而且回傳資料中有等號 =,就會視之為 FORM 類型的資料。 被 URL 編碼起來的等號 %3D 不在此例。 如果這樣,這些回傳資料會被設定為一個環境參數 QUERY_STRING 的值。 其實 CGI 定義了將近二十個環境參數,稍後再說些別的參數。 我們就不再多說關於 GET 的回傳方法了。
用 POST 方法回傳的資料,不寫在 URL 裡面,卻是用一種特別的內容方式傳回 httpd。 然後 CGI 會將這些參數原封不動地從 stdin 交給執行檔。 用 POST 方法回傳資料,CGI 程式還是可以得到一些環境參數。 但是此時 QUERY_STRING 這個參數沒有了,但是有以下參數可以用:
FORM 類型的回傳參數,就像以下形式
PARA=one%25&PARA=two+MORE它總是只有一列,也就是當中沒有裸露的 '\n'。 而且它不是以一個 NULL 字元結束。 它用一個 & 符號分隔兩個項目,因此若有 N-1 個 & 則共有 N 個項目。 每個項目都有一個裸露的 = 號, = 號左邊是參數名,右邊是對應的值。
一個 CGI 程式的最基本動作,就是解讀 (parsing) 輸入的字串。 這是一批麻煩的小東西。所幸已經有一些熱心人士替我們寫好了。 我選擇採用 Thomas Boutell 寫的 Cgic 程式庫。這是一批 ANSI C 函式, 幫助我們取得參數的值,並且轉換成方便的資料的型態。
課外讀物:
[1] NCSA 的 CGI 說明與範例文件
http://hoohoo.ncsa.uiuc.edu/cgi/
[2] Netscape Cookie 說明文件
http://www.netscape.com/newsref/std/cookie_spec.html
[3] ANSI C 的 CGI 輔助工具庫 (CGIC), by T. Boutell
http://www.boutell.com/cgic/
[4] Perl 5 的 CGI 輔助工具庫 (CGI.pm), by L. Stein
http://stein.cshl.org/WWW/software/CGI/cgi_docs.html
[5] C++ 的 CGI 輔助工具庫 libcgi++
單維彰
(C) Copyright 2001 Wei-Chang Shann 單維彰
建立:2001/04/11‧修改:2001/04/23