cgi資料

 

1.何謂CGI(Common Gateway Interface)程式 ?

一般的 HTML 文件內容在經過編輯整理後, 便固定不變(除非作者本身視需要修改). 可
是當文件中的資料會隨時間而變動時, 也就是說文件的內容並非一成不變的情況下, 上
述 " 固定式的 HTML " 文件便無能為力了. CGI程式就是為了建立 " 可變式 HTML "
所採用的一種方法之一.底下有一段英文說明, 不妨參考看看

The Common Gateway Interface, or CGI, is a standard for external gateway programs to
interface with information servers such as HTTP servers.

 

2.如何使用CGI程式呢 ?

在 HTML 文件中使用CGI程式的方法, 就如同其他種類的資源定位一般, 利用
<a href="http://電腦/目錄/CGI程式名稱">敘述</a>的方式來取
得資源.

 

3.用什麼語言來撰寫CGI程式呢 ?

可利用 UnixShell Script 來撰寫 CGI程式. 事實上, 只要是在 WWW
Server
上可以執行的可執行檔, 皆可以當作 CGI程式. 所以, 用什麼語言來撰寫
CGI程式都可以.

 

4. 一個簡易CGI程式寫作:現在幾點了???

date 程式內容如下:
------> date <------
#!/bin/sh
# 第一行的 #! 是 Unix shell script 的固定寫法
# 其後的 /bin/sh 是說這個CGI程式是在 /bin/sh 這個shell下執行
# 第二行後以 # 開頭的行,皆是當作註解使用

echo Content-type: text/plain
echo

# 上面這兩行是固定要寫的
# 事實上,經測試 echo Content-type: text/plain 這一行亦可省略
# 但是 echo 這一行一定要存在

echo -n '現在時間是 : '

# 顯示 '現在時間是 : ' 這段文字
# -n 參數表示印完文字後不換行

/bin/date

# 執行 Unix 中 date 的指令
--------------------

看看 date 這個CGI程式的執行結果吧!

5. CGI程式寫作:寫什麼就秀什麼???

print_input 程式內容如下:

------> print_input <------
#!/bin/sh

echo Content-type: text/html
echo

if [ $# = 0 ]; then

# 在 shell script 中 $# 代表傳到本程式的所有引數個數
# 當呼叫此程式時如未給任何參數, 則 $# = 0

# 下面這一段有特別的技巧, 叫做"行中的輸入重定向"
# 如果字串' << '在一命令之後,如 command << word
# 則 shell 會用其後的輸入行當作 command 命令的標準輸入,
# 直到碰到一行內只有字串 word 才停止.
# 下列幾行就是將 <TITLE> .......EOM 間的資料傳給 cat 命令
# 結果就是將這幾行字顯示在螢幕上.

cat << EOM
<TITLE>秀字程式</TITLE>
<H1>秀字程式</H1>

<ISINDEX>
您想印出"什麼東東",就在方格內輸入"什麼東東"
EOM

# <ISINDEX> 會產生一個輸入方格,讓您輸入任何東西
# 但是程式要在完全執行完畢後, 才讓您輸入東東( 特別注意這點 )
# 當您按下<Enter>時, 就會將輸入的資料當作本程式的引數
# 重新執行本程式.
#
# 在 shell script 中有幾個特別的參數
# 1. $# : 所有引數的個數
# 2. $0 : 目前這個程式的名稱
# 3. $1,$2,.. : 位置參數, 也就是第一個引數,第二個引數,..
# 4. $* : 所有的引數, 也就是 $* = $1 $2 ...

else

# 以下這一段是有輸入引數時才執行的, 也就是您在輸入方格
# 按下<Enter>後,再次執行本程式時才動作
# 請注意下面幾行的寫法和 HTML 文件的寫法完全相同, 只是都被包含在" "之間
# 並且都是用 echo 來顯示

echo "<pre>"
echo $*
echo "<hr>"
echo "<a href="/cgi-bin/print_input"><img src="/image/leftenter.gif">回秀字程式</a>"
echo "</pre>"
fi
---------------------------

看看 print_input 這個CGI程式的執行結果吧!

如果您未輸入任何東東,就按下<Enter>將會出現一個"應用程式錯誤"

 

6.第三個CGI程式寫作:酸甜苦辣留言版???

這個CGI程式需配合 HTML 中 FORM 及 INPUT 使用

首先,看看下面這個 HTML 文章( 注意:不是CGI程式喔!)

note_board.html 內容如下:

------> note_board.html <------
<html>
<title>酸 甜 苦 辣 留 言 版</title>
<body>
<h1>酸 甜 苦 辣 留 言 版</h1>
<hr>
當您看完了後,<br>
相信您也有話要說,<br>
別客氣, 通通寫在留言版上,<br>
我會一一參考改進,<br>
謝謝<p>
<form method=post action="/cgi-bin/note_board">
<pre>
您的大名 : <input name="visitor" size=42>
標 題 : <input name="subject" size=42>
</pre>
留言版很大, 不要浪費了, 想寫什麼就寫什麼, 歡喜就好!
<textarea name="comments" rows=15 cols=60>留言:</textarea><p>
<input type="submit" value="8-) 哈哈哈 確定留言!!!">
<input type="reset" value="8-< 寫錯了 擦掉重來!!!">
</form>
</body>
</html>

實例說明

上面這一部份要當作下面CGI程式的輸入界面. 請您注意一下<form ... >這一行的

"/cgi-bin/note_board", 這才是我們所要介紹的CGI程式.

下面的表格就是 note_board.html 所產生的.

酸 甜 苦 辣 留 言 版


當您看完了後,
相信您也有話要說,
別客氣, 通通寫在留言版上,
我會一一參考改進,
謝謝



您的大名 :
標 題 :

留言版很大, 不要浪費了, 想寫什麼就寫什麼, 歡喜就好! 留言:



或許您會問當已經寫好了, 要怎麼樣才能送出去呢? 其實很簡單, 您只要按下
"8-)哈哈哈 確定留言!!!" 這個按鈕, 就可以了.
接下來, 要講最重要的地方, 請您集中精神.

當您按下按鈕, 程式便將所有資料傳給 "/cgi-bin/note_board" 這個程式.

傳送的格式如下:

visitor=JoJo&subject=Just+test&comments=%AF%64%A8%A5%3A........

您可以清楚的看到下面的幾點:
a) 程式傳給 "/cgi-bin/note_board" 的資料只有一項, 就是 "visitor..." 這一項.
b) 變數的名稱(visitor,subject,comments)及出現順序, 皆與 note_board.html 中的一樣.
c) 變數間以 "&" 符號互相隔開.
d) 變數名稱和輸入變數值以 "=" 符號互相隔開.
e) 大小寫英文字母,數字,某些符號可以正確無誤的傳送.
f) 空白以 "+" 來代表. 其他符號以 "%符號的ASCII值" 來代表. 例如: ":"以"%3A"來代表.
g) 中文字則以兩位元的 BIG5 碼表示. 例如: "留"這個字的 BIG5 碼為 af64,
以"%AF%64"來表示.

看到這裡, 想必您已經猜到 "/cgi-bin/note_board"
這個CGI程式的作用就是讀取傳送到的資料, 將資料還原成原來的樣子,
並依照我們的需求來處理.

note_board 程式內容如下:

------> note_board <------
#!/bin/sh

echo Content-type: text/html
echo

read data
echo $data > /tmp/data.tmp

# 讀取資料並放入 /tmp/data.tmp 中

visitor=`cut -d"&" -f1,1 /tmp/data.tmp`
subject=`cut -d"&" -f2,2 /tmp/data.tmp`
comments=`cut -d"&" -f3,3 /tmp/data.tmp`

# 因變數間以 "&" 相互隔開, 故利用 cut 來得到單一變數.

echo $visitor > /tmp/data.tmp
visitor=`cut -d"=" -f2,2 /tmp/data.tmp`
echo $subject > /tmp/data.tmp
subject=`cut -d"=" -f2,2 /tmp/data.tmp`
echo $comments > /tmp/data.tmp
comments=`cut -d"=" -f2,2 /tmp/data.tmp`

# 因變數名稱與輸入變數值以 "=" 隔開, 故利用 cut 來得到輸入變數值.

rm /tmp/data.tmp

# 刪除暫存資料檔
# 至此, 我們已經得到每個變數的輸入值
# 以下便是依照個人需要來處理變數.

echo "Visitor : $visitor" >> /tmp/note
echo "Subject : $subject" >> /tmp/note
echo "Comments : $comments" >> /tmp/note
echo "---------------------------------------------------" >> /tmp/note

echo "<pre>"
echo "我已經記下您的留言,
"
echo "如果有需要, 我會儘快給您回信,
"
echo "謝謝.

" echo "<hr>" echo "<a
http://http://alpha.secc.fju.edu.tw/~macgyver/skill/cgi/tools_text.html#formend
src="/image/rightenter.gif"></a> 回CGI程式寫法說明." echo "</pre>"
------------------------------------------- 看看 note_board 這個CGI程式的執行結果吧!

 

仔細的您, 在看完上面的程式, 可能會有一個小小的疑問, 我們好像還沒有將被更改的

中文字, 符號 及空白恢復原狀? 沒錯, 目前為止, 我們只是取出變數值, 並依照需要予以

處理而已. 您或許會問為什麼我們沒有處理這些字碼的轉換的呢? 原因有二, 一則字碼

轉換程式可以適用於每個使用 FORM , INPUT 的CGI程式, 為了使用上的方便, 所以

寫成另外一個轉換程式; 二則如果每次有新的留言, 就執行轉換程式一遍, 只是徒然浪

費時間罷了. 基於上述兩個理由, 筆者另外寫了一個轉換程式, 只有當您想看留言的內

容時, 才執行轉換程式, 這樣就能達到省時又省力的目的.

使用 Unix Shell Script ( Bourne Shell ) 的一個轉換程式, 格式如下:

 trans (輸入檔)        ==> 直接輸出到螢幕

trans (輸入檔) > (輸出檔) ==> 輸出到目的檔案

以"酸甜苦辣留言版"這個CGI程式而言, 若想看留言的內容, 則需做下列的轉換工

作.

trans /tmp/note > Object_file

Object_file 就是所有留言的資料, 作者只要看這個檔案, 就可以知道您的寶貴意見囉!


7.第四個CGI程式寫作:讀者意見調查表???

這個CGI程式將使用到 HTML 中的 FORM , INPUT 及 SELECT 等功能, 並配合一個

極簡易的讀者意見調查資料庫工作.

reader 內容如下:

------> reader <------
#!/bin/sh

echo Content-type: text/html
echo

if [ $# != 0 ]
then

# 當呼叫 reader 時, 若有給定參數(也就是輸入資料), 則會執行下面的程式段.
# 這部份程式段的功能在將讀者輸入的個人資料, 和調查結果分別取出.
# 然後加入讀者意見調查資料庫中.

read data
name=`echo $data | cut -d"&" -f1,1 | cut -d"=" -f2,2 | /home/User/WWW/cern_httpd_3.0/docs/work/trans | cut -c1-6`

# 將名字由 data 中取出, 經過 trans 轉換成中文, 然後只取前 6
# 個字母(三個中文字)來顯示.

sex=`echo $data | cut -d"&" -f2,2 | cut -d"=" -f2,2`

# 取出性別的輸入資料

unit1=`echo $data | grep "unit1" | /usr/ucb/wc -l`
unit2=`echo $data | grep "unit2" | /usr/ucb/wc -l`
unit3=`echo $data | grep "unit3" | /usr/ucb/wc -l`
unit4=`echo $data | grep "unit4" | /usr/ucb/wc -l`
value1=`echo $data | grep "value1" | /usr/ucb/wc -l`
value2=`echo $data | grep "value2" | /usr/ucb/wc -l`
value3=`echo $data | grep "value3" | /usr/ucb/wc -l`
value4=`echo $data | grep "value4" | /usr/ucb/wc -l`
value5=`echo $data | grep "value5" | /usr/ucb/wc -l`

# 分別設定 unit1-4 , value1-5 之值.
# 1 : 表示得到一票 0 : 表示沒有.
# unit1-4 分別表示四個 CGI 單元得票與否.
# value1-5 分別表示您對本文的評價等級.

echo "<pre>"
echo $name'~'$sex'~'$unit1$unit2$unit3$unit4'~'$value1$value2$value3$value4$value5 | tr ~ '\11' >> /home/User/WWW/cern_httpd_3.0/docs/work/reader.db
echo "</pre>"

# 這三行是把讀者的輸入資料, 加入讀者意見調查資料庫中.

fi

# cat << EOM
# ... anything ...
# EOM

# 下面的內容, 就是使用者所看到的表格.

cat << EOM
<title>讀 者 意 見 調 查 表</title>
<center><h1>讀 者 意 見 調 查 表</h1></center>
<hr>
<form method=post action="/cgi-bin/reader??">
<dl>
<dt>◎ 您的基本資料:
<p>
<dd>您的大名:<input name="name" size=16>
<dd>您的性別:<input type="radio" name="sex" value="man" checked> ♂
<input type="radio" name="sex" value="woman"> ♀
<p>
<dt>◎ 您最喜歡的單元:(複選)
<p>
<dd><input type="checkbox" name="unit" value="unit1">現在幾點了???
<dd><input type="checkbox" name="unit" value="unit2">寫什麼就秀什麼???
<dd><input type="checkbox" name="unit" value="unit3">酸甜苦辣留言版???
<dd><input type="checkbox" name="unit" value="unit4">讀者意見調查表???
<p><p>
<dt>◎ 您對於”CGI程式寫法說明”的評價:
<p>
<dd><select name="value" size=1>
<option value="value1">好極了
<option value="value2"> 好
<option value="value3">普 通
<option value="value4"> 爛
<option value="value5">爛透了
</select>
<dt><hr>
<dd><input type="reset" value="重寫一張"><input type="submit" value="投進票箱">
<dt><hr>
</dl>
</form>
<pre>
<h3>目前意見調查情形如下:</h3>

           單單單單      好 普 爛
姓  名 姓 別   元元元元      極好 爛透
           一二三四      了 通 了
</pre>
EOM
echo "<pre>"
cat /home/User/WWW/cern_httpd_3.0/docs/work/reader.db
echo "</pre>"

# 上面這幾行就是列印選項說明及讀者調查資料庫的資料.

echo "<hr>"

----------------------------------------------------------


這個CGI程式的 key point 有兩點:
首先, 請注意程式中如下的這一行

<form method=post action="/cgi-bin/reader??">
              ︿︿︿︿
看到了嗎?有兩個奇怪的”?”在CGI程式 reader 的後面. 這兩個問號( 三個問號也

可以 )的作用是把讀者輸入 的資料傳給自己 (也就是 reader), 如果不加上這兩個問號,

則只是執行 reader 而已, 並不將讀者輸入的資料傳入.看到這裡, 您當會發現這個

CGI程式執行時, 可能有兩種情況, 不帶參數和帶參數兩種. 不帶參數的情況發生在

html 直接呼叫 reader . 而帶參數的情況發生在由 FORM 呼叫 reader 時, 也就是讀者輸入資料, 然後按下 submit 或 return 時.

由於上述兩種執行情況的不同, 才產生第二個 key point , 也就是


if [ $# != 0 ]
then
...
fi

這個 if ... else ... fi 的結構. 當執行 reader 且沒有參數 ( #$ =0 ) 時, 就會略過這段程式.

如果附帶有參數 ( $# != 0 ) 時, 則會執行這段程式碼. 而這段程式就是負責處理讀者的

輸入資料, 並將該資料加入讀者意見調查資料庫中.

讀者意見調查資料庫( reader.db )的格式如下, 提供您參考看看:

王小明 man 0 0 0 1 1 0 0 0 0
kevin  man 1 1 1 1 0 1 0 0 0
...... ... ....... .........





環境變數

很多重要的 CGI 應用程式需要的訊息都是由 UNIX 環境變數所提供的. 在 Perl 中可由

$ENV 來取得環境變數

 

CGI 環境變數
環境變數 說明
GATEWAY_INTERFACE Server 使用的 CGI 版本
SERVER_NAME Server 的 host 名稱或 IP 位址
SERVER_SOFTWARE 回應 client request 的 Server 軟體名稱和版本
SERVER_PROTOCOL 傳遞資訊所用的協定名稱或版本
SERVER_PORT Server 正在執行的 port number
REQUEST_METHOD 發出 request 的方法
PATH_INFO 傳遞給 CGI 程式的額外路徑
PATH_TRANSLATED 存在 PATH_INFO 中的給定路徑的傳遞版本
SCRIPT_NAME 程式執行時的 virtual path
DOCUMENT_ROOT 網路提供的文件服務所在路徑
QUERY_STRING 傳遞給程式的 query 資訊
REMOTE_HOST 使用者發出 request 的遠端 host 名稱
REMOTE_ADDR 使用者發出 request 的遠端 IP 位址
AUTH_TYPE 用來確定使用者合法性的鑑定方法
REMOTE_USER 使用者的合法名稱
REMOTE_IDENT 發出 request 的使用者
CONTENT_TYPE query 資料中的 MIME 型別
CONTENT_LENGTH 資料長度,以 byte 或字元數來計算
HTTP_FORM 使用者發出 request 的電子郵件訊息
HTTP_ACCEPT client 可以接受的 MIME 型別列表
HTTP_USER_AGENT client 用來發出 request 的瀏灠器
HTTP_REFERER 在讀取 CGI 程式前,client 所指的文件 URL

回到前頁