相關模塊 | 相關指令 |
---|---|
CGI(公共網關接口[Common Gateway Interface])定義了網站服務器與外部內容協商程序之間交互的方法,一般是指CGI程序或者CGI腳本,是在網站上實現動態頁面的最簡單而經常使用的方法。本文將對如何在Apache網站服務器上創建CGI以及如何編寫CGI程序做介紹。html
要讓CGI程序能正常運做,必須配置Apache以容許CGI的執行,其方法有多種。程序員
ScriptAlias
指令使Apache容許執行一個特定目錄中的CGI程序。當客戶端請求此特定目錄中的資源時,Apache假定其中文件都是CGI程序並試圖運行。web
ScriptAlias
指令形如:shell
ScriptAlias /cgi-bin/ /usr/local/apache/cgi-bin/
apache
若是Apache被安裝到默認的位置,默認的配置文件httpd.conf
中則會有上述配置。ScriptAlias
指令定義了映射到一個特定目錄的URL前綴,與Alias
指令很是類似,二者通常都用於指定位於DocumentRoot
目錄之外的目錄,其區別是ScriptAlias
又多了一層含義,即其URL前綴中任何文件都被視爲CGI程序。因此,上述例子會指示Apache,/cgi-bin/
應該指向/usr/local/apache/cgi-bin/
目錄,且視之爲CGI程序。編程
舉例,若是有URL爲http://www.example.com/cgi-bin/test.pl
的請求,Apache會試圖執行/usr/local/apache/cgi-bin/test.pl
文件並返回其輸出。固然,這個文件必須存在並且可執行,並以特定的方法產生輸出,不然Apache返回一個出錯消息。瀏覽器
因爲安全緣由,CGI程序一般被限制在ScriptAlias
指定的目錄中,如此,管理員就能夠嚴格地控制誰可使用CGI程序。可是,若是採起了恰當的安全方法措施,則沒有理由不容許其餘目錄中的CGI程序運行。好比,你可能但願用戶在UserDir
指定的宿主目錄中存放頁面,而他們有本身的CGI程序,但無權存取cgi-bin
目錄,這樣,就產生了運行其餘目錄中CGI程序的需求。安全
能夠在主服務器配置文件中,使用Options
指令顯式地容許特定目錄中CGI的執行:服務器
<Directory /usr/local/apache/htdocs/somedir>
網絡
Options +ExecCGI
</Directory>
上述指令使Apache容許CGI文件的執行。另外,還必須告訴服務器哪些文件是CGI文件。下面的AddHandler
指令告訴服務器全部帶有cgi
或pl
後綴的文件是CGI程序:
AddHandler cgi-script cgi pl
.htaccess
文件是針對目錄進行配置的一種方法。Apache在提供一個資源時,會在此資源所在目錄中尋找.htaccess
文件,若是有,則使其中的指令生效。AllowOverride
指令決定了.htaccess
文件是否有效,它指定了哪些指令能夠出如今其中,或者根本不容許使用。爲此,須要在主服務器配置中如此配置:
AllowOverride Options
在.htaccess
文件中,須要如此配置:
Options +ExecCGI
以使Apache容許此目錄中CGI程序的執行。
編寫CGI程序和``常規''程序之間有兩個主要的不一樣。
首先,在CGI程序的全部輸出前面必須有一個MIME類型的頭,即HTTP頭,對瀏覽器指明所接收內容的類型,大多數狀況下,形如:
Content-type: text/html
其次,輸出要求是HTML形式的,或者是瀏覽器能夠顯示的其餘某種形式。多數狀況下,輸出是HTML形式的,但偶然也會編寫CGI程序以輸出一個gif圖片或者其餘非HTML的內容。
除了這兩點,編寫CGI程序和編寫其餘程序大體相同。
這個CGI程序例子在瀏覽器中打印一行文字。把下列存爲first.pl
文件,並放在你的cgi-bin
目錄中。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, World.";
即便不熟悉Perl語言,你也應該能看出它幹了什麼。第一行,告訴Apache這個文件能夠用/usr/bin/perl
(或者任何你正在使用的shell)解釋並執行。第二行,打印上述要求的內容類型說明,並帶有兩個換行,在頭後面留出空行,以示HTTP頭的結束。第三行,打印文字``Hello, World.''。程序到此結束。
打開你喜歡的瀏覽器並輸入地址:
http://www.example.com/cgi-bin/first.pl
或者是你存放程序的其餘位置,就能夠在瀏覽器窗口中看到一行Hello, World.
。雖然並不怎麼激動人心,可是一旦這個程序能正常運做,那麼就可能運做其餘任何程序。
從網絡訪問CGI程序,瀏覽器中可能會發生四種狀況:
記住,服務器不是以你的用戶身份運行的,就是說,在服務器啓動後,擁有的是一個非特權用戶的權限-一般是``nobody''或者``www'' -而須要更大的權限以容許文件的執行。一般,給予``nobody''足夠的權限以執行文件的方法是,對文件賦予everyone execute權限:
chmod a+x first.pl
另外,若是須要對其餘文件進行讀取或寫入,也必須對這些文件賦予正確的權限。
若是服務器被配置爲使用suexec則是一個例外。這個程序容許CGI程序根據其所在虛擬主機或用戶宿主目錄的不一樣而以不一樣的用戶權限運行。Suexec有極其嚴格的權限校驗,任何校驗失敗都會使CGI程序運行失敗而產生"Internal Server Error"。對此,須要檢查suexec的日誌文件以發現哪一個安全校驗出問題了。
當你在命令行執行一個程序,某些信息會自動傳給shell而無須你操心,好比一個路徑,告訴shell你所引用的文件能夠在哪兒找到。
可是,在CGI程序經過網站服務器執行時,則沒有此路徑,因此,你在CGI程序中引用的任何程序(如sendmail)都必須指定其完整的路徑,使shell能找到它們以執行你的CGI程序。
一種普通的用法是,在CGI程序的第一行中指明解釋器(一般是perl
),形如:
#!/usr/bin/perl
必須保證它的確指向解釋器。
多數CGI程序失敗的緣由在於程序自己有問題,尤爲是在已經消除上述兩種錯誤而CGI掛起的狀況下。在用瀏覽器測試之前,先在命令行中執行你的程序,可以發現大多數的問題。
出錯記錄是你的朋友。任何錯誤都會在出錯記錄中有記載,因此你應該首先查看它。若是你的網站空間提供者不容許訪問出錯記錄,那麼你應該考慮換一個空間提供者。學會閱讀出錯記錄,能夠快速找出問題並快速解決。
當你的CGI編程逐漸深刻,理解幕後的操做,尤爲是瀏覽器和服務器如何與其餘的通信,就變得有用了。雖然成功地寫了一個程序打印``Hello, World.'',但並無實際的用處。
環境變量是使用計算機時處處都會用到的變量,好比路徑(對實際文件的一個搜索路徑以補全你的輸入)、你的用戶名以及你的終端類型等等。在命令行輸入env
,能夠獲得你的標準的當天的環境變量列表。
在CGI處理過程當中,服務器和瀏覽器都會設置環境變量,好比瀏覽器類型(Netscape, IE, Lynx)、服務器類型(Apache, IIS, WebSite)以及將要執行的CGI程序名稱等等。
全部這些變量對CGI程序員都有效,但只是客戶端-服務器通信的一半內容。完整的變量列表見http://hoohoo.ncsa.uiuc.edu/cgi/env.html
這個簡單的CGI程序列出了環境中全部的環境變量,Apache發行版的cgi-bin
中還有兩個相似的程序。注意,有些變量是必須的,有些則是可選的,因此你可能會看見一些官方列表中沒有的變量。另外,Apache提供了多種不一樣方法以在默認提供的變量中增長你的專用環境變量。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
foreach $key (keys %ENV) {
print "$key --> $ENV{$key}<br>";
}
服務器和客戶端之間的其餘通信都經過標準輸入設備(STDIN
)和標準輸出設備(STDOUT
)完成。一般,STDIN
是指鍵盤或者一個程序所做用於的一個文件,STDOUT
指控制檯或顯示器。
當你POST
一個網絡表格到一個CGI程序時,表格中的數據被捆紮爲一個特殊形式經過STDIN
傳送給CGI程序,這樣,這個程序就能夠處理這些數據,彷彿這些數據來自鍵盤或者一個文件。
這種``特殊形式''很簡單,一個字段名稱及其值,中間用等號(=)鏈接,多個這樣的字段對用與符號(&)鏈接。很是規字符,如空格、與符號和等號,被轉換爲其等值的十六進制以避免出問題。整個字串形如:
name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey
有時,你會發現URL後面綴有這樣的字串。這種形式會使服務器以這個字串的內容設置環境變量QUERY_STRING
,稱爲GET
請求。你的HTML表格在FORM
標記中設置METHOD
屬性,以指定傳送數據的行爲使GET
或者是POST
。
接着,你的程序必須把這個字串分離以得到有用的信息。所幸,有庫和模塊能夠幫助你處理這些數據,還有爲你的CGI程序達成其餘目的的處理器。
編寫CGI程序時,你應該考慮使用代碼庫或模塊來完成多數瑣碎的工做,以減小錯誤並更快地開發。
若是用Perl語言編寫CGI程序,可用的模塊見CPAN,最經常使用的模塊是CGI.pm。也能夠考慮用CGI::Lite,它實現了一個在多數程序中全部必須的最小功能集
若是用C語言編寫CGI程序,則有不少選擇,其中之一是CGIC庫,來自http://www.boutell.com/cgic/。
網上有大量的CGI資源。能夠在Usenet組comp.infosystems.www.authoring.cgi和別人討論CGI相關問題。HTML Writers Guild的-servers郵件列表是一個優秀的問題解答資源。更多資源能夠在http://www.hwg.org/lists/hwg-servers/找到。
另外,還能夠閱讀CGI規範,其中有CGI程序操做的全部細節,原始版本見NCSA,另有一個更新草案見Common Gateway Interface RFC project。
當你向一個郵件列表或者新聞組提交CGI相關問題時,你應該確保提供了足夠的信息以更簡單地發現並解決問題,諸如:發生了什麼事、你但願獲得什麼結果、結果與你所指望的有什麼出入、你運行的服務器、CGI程序是用什麼語言編寫的、若是可能就提供那個討厭的代碼。
注意,毫不要把CGI相關問題提交到Apache bug database,除非你堅信發現的是Apache源代碼中的問題。