Common Gateway Interface

這 份 文 件 適 合 800x600, 16 色 顯 示 , 具 Table 功 能 的 瀏 覽 器


CGI 的功能, 為什麼要 CGI?

CGI 是 一 種 介 面 .

當 您 想 要 使 W3程 式 結 合, 就 需 要 用 CGI .

一 般 來 說 , HTML 檔 案 是 屬 於 靜 態 的 資 料 . 雖 然 可 以 呈 現 文 字 、 聲 音 、 影 像 乃 至 於 動 畫 等 多 媒 體 資 料 , 但 終 究 只 是 展 示 固 定 資 料 的 一 種 方 式 . 如 果 想 要 列 出 像 是 在 資 料 庫 中 隨 時 會 變 動 的 資 料 , 立 刻 捉 襟 見 肘 .

CGI 是什麼

基 本 上 , 我 們 知 道 W3 是 如 下 圖 的 主 從 架 構 .

W3 主從架構

以 程 式 的 觀 點 , 在 W3 使 用 者 端 要 有 所 謂 的 瀏 覽 器 (Browser) , 如 : Netscape 、 Mosaic ... ; 而 W3 伺 服 器 則 必 須 存 在 一 個 伺 服 程 式 (Daemon), 通 常 被 統 稱 為 HTTPD. 另 外 , 還 要 有 一 些 事 先 寫 好 的 HTML 檔 、 圖 形 檔 ... 等 .

W3 主從架構程式

W3 使 用 者 就 透 過 HTTPD 取 得 想 要 看 的 HTML 檔 、 圖 形 檔 , 但 這 些 檔 都 是 固 定 內 容 . 除 了 以 編 輯 器 (Editor) 來 編 輯 更 動 , 否 則 使 用 者 看 到 東 西 都 會 是 一 樣 的 .

今 天 絕 大 部 分 的 HTTPD 都 支 援 CGI , 讓 HTTPD 與 一 般 程 式 溝 通 , 達 到 顯 示 動 態 資 料 的 效 果 (可 用 程 式 控 制 W3 的 顯 示) . 這 並 沒 有 限 定 使 用 那 種 程 式 , 只 要 符 合 CGI 規 格 的 程 式 就 被 稱 為 CGI 程 式 .

實作的準備

接 下 來 的 內 容 是 以 perl 為 例 , 引 導 讀 者 撰 寫 CGI 程 式 . 如 果 要 實 際 操 作 , 您 必 須 準 備 好 perl 這 個 直 譯 程 式 . 當 然 也 可 在 瞭 解 後 , 用 自 己 熟 悉 的 程 式 語 言 .

如 果 您 不 瞭 解 perl , 可 把 它 視 為 C 與 BASIC 的 混 合 . 我 們 儘 量 避 免 使 用 艱 澀 的 語 法 .

再 來 要 知 道 HTTPD 執 行 CGI 程 式 的 方 式 . 大 部 分 的 HTTPD 都 是 把 CGI 程 式 集 中 放 在 一 個 目 錄 裡 , 因 此 只 有

  1. 你 是 系 統 管 理 者 或 自 己 執 行 W3 伺 服 程 式
  2. 和 系 統 管 理 者 有 交 情
  3. 系 統 管 理 者 開 放 CGI 程 式 的 目 錄

這 些 情 況 下 , 才 有 機 會 寫 CGI 程 式 .

有 些 HTTPD 會 依 MIME 型 態 定 義輸 出 檔 案 形 式 來 決 定 是 否 為 CGI 程 式 , 這 時 使 用 者 可 在 自 己 的 目 錄 下 撰 寫 CGI 程 式 . 若 不 確 定 自 己 的 HTTPD 是 否 有 這 種 功 能 , 可 查 閱 Paul E. Hoffman 先 生 整 理 的 W3 伺 服 器 比 較 , 看 看 在 各 項 資 料 的 Script or action based on output file typeScript or action based on MIME content-type 是 Yes 還 是 No .

接 下 來 的 例 子 , 是 在 下 面 的 條 件 成 立 :

  1. perl 直 譯 器 的 版 本 是 4.036 , 並 且 可 以 正 確 執 行 perl 的 程 式
  2. 放 置 perl 的 目 錄 名 稱 在 PATH 環 境 變 數 中
  3. CGI 程 式 在 /cgi-bin 目 錄 裡 可 被 HTTPD 執 行
  4. 您 必 須 瞭 解 HTML 語 法

第一個 CGI 程式

檔名 : /cgi-bin/t-cgi1.pl
#!/usr/local/bin/perl
srand;
print "Content-type: text/html\n\n";
print "<title>t-cgi1.pl</title>\n";
print "<h1>魔 術 數 字 : ", int(rand(100000)), "</h1>\n";
執行 t-cgi1.pl

上 面 的 寫 法 是 為 了 方 便 讀 者 剪 貼 (Copy & Paste) . 可 以 在 /cgi-bin 下 編 輯 檔 案 t-cgi1.pl , 然 後 把 兩 個 框 框 之 間 共 5 列 的 內 容 貼 上 (Paste) .

說 明 (以 下 各 點 代 表 列 號) :

  1. UNIX Shell 解 譯 命 令 檔 (Script) 時 指 定 的 處 理 程 式 (NT 可 省 略 此 列)
  2. 設 定 亂 數 種 子
  3. Content-type: 」 告 知 W3 以 下 輸 出 內 容 的 MIME 型 態 為 「text/html」, 就 是 html 格 式
  4. 明 顯 的 , 這 一 列 用 來 顯 示 標 題 (title)
  5. 使 用 <h1></h1> 使 字 體 放 大 . int(rand(100000)) 結 果 是 0 - 99999 的 隨 機 整 數 . 很 BASIC 的 語 法 , 以 「,」 連 接 要 顯 示 的 資 料 .

我 們 「執行 t-cgi1.pl」 是 寫 成 「<a href="/cgi-bin/t-cgi1.pl">執行 t-cgi1.pl</a>」 . 只 要 點 取 (Point & Click) 就 可 以 讓 t-cgi1.pl 這 個 CGI 程 式 執 行 , 然 後 看 到 結 果 .

HTTPD 送 出 資 料 不 再 是 取 用 存 在 的 HTML 檔 、 圖 形 檔 ...

HTTPD HTML 靜態資料

而 是 執 行 CGI 程 式 , 動 態 產 生 資 料 .

HTTPD CGI 動態資料

HTML 檔 到 HTTPD 的 資 料 是 HTML 檔 案 的 內 容 , 那 CGI 程 式 到 HTTPD 的 資 料 呢 ? 以 t-cgi1.pl 來 說 , 其 資 料 內 容 透 過 標 準 輸 出 (Stdout) 至 HTTPD , 輸 出 的 資 料 就 是 底 下 框 框 裡 所 列 :

Content-type: text/html

<title>t-cgi1.pl</title>
<h1>魔 術 數 字 : XXXX</h1>
「XXXX」 為 不 定 的 隨 機 變 數 .

要 注 意 的 , 以 Content-type: text/html 指 定 資 料 MIME 型 態 之 後 必 須 有 兩 個 換 列 字 元 才 能 接 續 其 它 資 料 .

現 在 應 該 有 能 力 擴 增 上 述 程 式 , 使 它 讀 取 資 料 庫 中 的 紀 錄 , 然 後 透 過 W3 顯 示 . 這 些 都 屬 於 單 向 , 亦 即 僅 讓 W3 動 態 顯 示 . 想 要 使 W3 接 受 使 用 者 輸 入 的 資 料 , 需 要 多 一 點 技 術 .

接受使用者輸入的 HTML 標籤 (tag)

這 邊 提 的 是 一 些 要 使 用 者 輸 入 資 料 的 HTML 語 法 . 以 下 各 個 說 明 , 會 有 <form></form> 標 籤 , 我 們 安 排 在 執 行 CGI 程 式 這 部 分 做 說 明 . 瀏 覽 時 , 先 不 深 究 .

不 妨 把 表 格 想 像 成 製 作 問 卷 調 查 所 需 要 的 項 目 .

簡 單 的 問 卷 會 有 單 選複 選 . 有 時 候 選 擇 項 目 太 多 , 恐 怕 版 面 變 得 零 亂 , 我 們 可 利 用 視 窗 環 境 的 特 點 : 捲 動 軸 選 擇 來 做 . 還 有 些 會 要 填 學 校 / 工 作 單 位 或 身 份 證 字 號 ... 等 屬 於 單 列 文 字 資 料 , 也 有 要 寫 寫 建 議 之 類 的 多 列 文 字 . 當 使 用 者 輸 入 的 資 料 有 保 密 的 必 要 , 不 希 望 輸 入 資 料 時 , 過 往 的 人 群 都 看 得 到 (例 如 某 些 情 況 下 , 會 對 出 生 年 、 月 、 日 敏 感) , 可 以 使 用 密 碼 式 單 列 文 字 輸 入 . 如 果 同 一 份 問 卷 , 可 能 因 為 填 寫 的 族 群 不 同 會 要 分 A 、 B 卷 , 這 時 隱 藏 式 資 料 就 派 上 用 場 .

另 外 , W3 的 表 格 有 可 點 取 圖 形 的 能 力 . 和 <img>ismap 能 力 相 彷 .

最 後 , 和 一 般 問 卷 較 大 的 不 同 在 於 如 何 使 W3 伺 服 器 去 執 行 CGI 程 式 . 是 我 們 在 此 需 要 瞭 解 的 重 點 .

CGI 程式如何接收使用者的輸入資料

CGI 程 式 是 利 用 標 準 輸 出 (Stdout) 將 資 料 送 至 HTTPD , HTTPD 則 是 透 過 標 準 輸 入 (Stdin)環 境 變 數 (Environ. Variable) 把 接 收 到 的 使 用 者 輸 入 , 傳 給 CGI 程 式 .

CGI 程式與 HTTPD 傳遞資料
  1. CGI 程 式 利 用 標 準 輸 出 (Stdout) 將 資 料 送 至 HTTPD
  2. HTTPD 透 過 標 準 輸 入 (Stdin) 將 資 料 傳 給 CGI 程 式
  3. HTTPD 透 過 環 境 變 數 (Environ. Variable) 將 資 料 傳 給 CGI 程 式

前 面 展 示 過 CGI 程 式 傳 給 HTTPD 資 料 內 容 , 現 在 來 看 看 HTTPD 傳 給 CGI 程 式 資 料 的 模 樣

job=%BA%DE%B2z%A4H%AD%FB&age=24&sex=%A4k&email=cynthia@www.fido.net.tw&comments=N%2FA

以 上 的 資 料 被 稱 為 URL 編 碼 字 串 (URL-Encoded strings) , 是 在 範 例 GET 版 本 或 POST 版 本 中 輸 入 :

職業          管理人員
年齡          24
性別          女
電子郵件地址   cynthia@www.fido.net.tw
建議          N/A

所 得 到 的 結 果 .

在 處 理 上 , 一 般 遵 循 下 面 步 驟 :

  1. 判 斷 是 用 GET 或 POST 傳 遞 資 料
  2. URL 編 碼 字 串 切 割 (以 & 分 段) , 取 得 參 數 對 (NAME=VALUE pairs)
  3. 將 編 碼 部 分 還 原 --- 先 將 + 轉 為 空 白 (space) , 再 把 %xx (xx 為 16 進 位) 轉 為 單 一 字 元

處 理 範 例 的 GET 版 本 或 POST 版 本


在 WebSite 執行的 CGI 程式

基本範例:

資料庫的使用範例:


在 伺 服 器 動 態 改 變 資 料 Server Push 範 例

在 使 用 者 端 要 求 改 變 資 料 Client Pull 範 例


INTERNET STUDIO 網路教材
若有任何建議或意見, 歡迎寫信到 tutor@www.fido.net.tw