通用網關接口CGI,是一組標準定義之間交換信息的Web服務器和自定義腳本。
維護NCSA和NCSA CGI規範定義CGI如下:
通用網關接口CGI,是一個標準的外部網關程序接口與信息服務器,如HTTP服務器。
目前的版本是CGI/1.1和CGI/1.2正在進行中。
要理解這個概念的CGI,讓我們看看會發生什麼,當我們點擊一個超鏈接,瀏覽特定網頁或URL。
您的瀏覽器輸入URL,即HTTP Web服務器請求的.文件名。
Web服務器將解析URL,並請求其中文件名,如果找到這個文件則發送回瀏覽器,否則發送一個錯誤消息,顯示你所請求的是一個錯誤的文件。
Web瀏覽器從Web服務器響應,並顯示接收到的文件或錯誤消息。
但是,它是可能的設置了HTTP服務器,所以,每當請求一個特定的目錄中的一個文件的文件冇有被發送回來;相反,它是執行一個程序,無論該程序的輸出被發送回您的瀏覽器顯示。這個函數被調用的通用網關接口CGI和程序稱為CGI腳本。這些CGI程序可以是一個Perl腳本,shell腳本,C或C ++程序等。
在你進行CGI編程之前,請確保您的Web服務器支持CGI,它被配置為處理CGI程序。由HTTP服務器來執行所有的CGI程序保持在一個預先配置的目錄。此目錄被稱為CGI目錄,並按照約定,它被命名為/cgi-bin目錄。通過慣例的PERL CGI文件擴展名為.cgi。
下麵是一個簡單的鏈接,鏈接到CGI腳本稱為hello.cgi。該文件被保存在的/cgi-bin/目錄下,它有以下內容。在你的CGI程序之前,請確保改變文件權限,使用chmod 755 hello.cgi的UNIX命令模式。
#!/usr/bin/perl print "Content-type:text/html\r\n\r\n"; print '<html>'; print '<head>'; print '<title>Hello Word - First CGI Program</title>'; print '</head>'; print '<body>'; print '<h2>Hello Word! This is my first CGI program</h2>'; print '</body>'; print '</html>'; 1; If you click hello.cgi then this produces following output:Hello Word! This is my first CGI program
hello.cgi 是一個簡單的腳本,它在將STDOUT(標準輸出)文件到IE屏幕。有一個重要的和額外的功能,這是要打印的第一行 Content-type:text/html\r\n\r\n. 這一行被發送回給瀏覽器,並指定該內容類型被顯示在瀏覽器畫麵上。現在你必須理解CGI的基本概念,你可以使用PERL寫很多複雜的CGI程序。這個腳本可以與任何其他外部係統交換信息,如RDBMS。
Content-type:text/html\r\n\r\n 這一行是HTTP頭的一部分,這是發送給瀏覽器能理解的內容。所有的HTTP報頭將在下麵的表格
HTTP Field Name: Field Content For Example Content-type:text/html\r\n\r\n
還有其他一些重要的HTTP報頭,你將經常使用在CGI編程。
Header | Description |
Content-type: String | A MIME string defining the format of the file being returned. Example is Content-type:text/html |
Expires: Date String | The date the information becomes invalid. This should be used by the browser to decide when a page needs to be refreshed. A valid date string should be in the format 01 Jan 1998 12:00:00 GMT. |
Location: URL String | The URL that should be returned instead of the URL requested. You can use this filed to redirect a request to any file. |
Last-modified: String | The date of last modification of the resource. |
Content-length: String | The length, in bytes, of the data being returned. The browser uses this value to report the estimated download time for a file. |
Set-Cookie: String | Set the cookie passed through the string |
所有的CGI程序,將有機會獲得以下環境變量。這些變量中發揮了重要作用,當在編寫任何CGI程序時。
Variable Name | Description |
CONTENT_TYPE | The data type of the content. Used when the client is sending attached content to the server. For example file upload etc. |
CONTENT_LENGTH | The length of the query information. It's available only for POST requests |
HTTP_COOKIE | Return the set cookies in the form of key & value pair. |
HTTP_USER_AGENT | The User-Agent request-header field contains information about the user agent originating the request. Its name of the web browser. |
PATH_INFO | The path for the CGI script. |
QUERY_STRING | The URL-encoded information that is sent with GET method request. |
REMOTE_ADDR | The IP address of the remote host making the request. This can be useful for logging or for authentication purpose. |
REMOTE_HOST | The fully qualified name of the host making the request. If this information is not available then REMOTE_ADDR can be used to get IR address. |
REQUEST_METHOD | The method used to make the request. The most common methods are GET and POST. |
SCRIPT_FILENAME | The full path to the CGI script. |
SCRIPT_NAME | The name of the CGI script. |
SERVER_NAME | The server's hostname or IP Address |
SERVER_SOFTWARE | The name and version of the software the server is running. |
這裡是小的CGI程序列出所有的CGI變量。
#!/usr/bin/perl print "Content-type: text/html\n\n"; print "<font size=+1>Environment</font>\n"; foreach (sort keys %ENV) { print "<b>$_</b>: $ENV{$_}<br>\n"; } 1;
有時它需要一個使用就點擊一個鏈接,你想給的選項,它會彈出一個“文件下載”對話框中的用戶,這很容易將附件通過HTTP頭,而不是顯示實際內容。
從上一節中提到的頭,這個HTTP頭會有所不同。
例如,如果你想從一個給定的鏈接下載一個文件名(FileName)文件,那麼它的語法如下所示。
#!/usr/bin/perl # HTTP Header print "Content-Type:application/octet-stream; name=\"FileName\"\r\n"; print "Content-Disposition: attachment; filename=\"FileName\"\r\n\n"; # Actual File Content will go hear. open( FILE, "<FileName" ); while(read(FILE, $buffer, 100) ) { print("$buffer"); }
可能所遇到的有很多情況,如,你需要從您的瀏覽器傳遞一些信息到Web服務器並最終到達CGI程序。最常見的瀏覽器使用兩種方法將此信息傳遞到Web服務器。這些方法是GET方法和POST方法。
GET方法發送編碼的用戶信息添加到頁麵請求。頁頁已編碼的信息中分離由 '?' 字符如下:
http://www.gitbook.net/cgi-bin/hello.cgi?key1=value1&key2=value2
GET方法是默認的方法來傳遞信息,從瀏覽器到Web服務器,它會產生一個很長的字符串出現在瀏覽器的位置:框中。不要使用GET方法,如果你有密碼或其他敏感信息傳遞給服務器。GET方法有大小限製:隻有1024個字符,可以在一個請求字符串。
這個信息被傳遞使用QUERY_STRING頭和通過QUERY_STRING環境變量將在CGI的程序中訪問。
您可以通過簡單的連接鍵 - 值對的任何URL或傳遞信息,您可以使用HTML <FORM> 標簽使用GET方法傳遞信息。
下麵是一個簡單的URL將傳遞兩個值,hello_get.cgi程序使用GET方法。
下麵是hello_get.cgi腳本來處理Web瀏覽器所提供的輸入。
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "GET") { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $first_name = $FORM{first_name}; $last_name = $FORM{last_name}; print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title>Hello - Second CGI Program</title>"; print "</head>"; print "<body>"; print "<h2>Hello $first_name $last_name - Second CGI Program</h2>"; print "</body>"; print "</html>"; 1;
下麵是一個簡單的例子,通過兩個值,使用HTML表單和提交按鈕。我們將使用相同的CGI腳本hello_get.cgi的來處理這個輸入。
<FORM action="/cgi-bin/hello_get.cgi" method="GET"> First Name: <input type="text" name="first_name"> <br> Last Name: <input type="text" name="last_name"> <input type="submit" value="Submit"> </FORM>
這是上述表單輸入第一個和最後一個名稱,然後單擊“提交”按鈕來查看結果。
一般信息傳遞給CGI程序更可靠的方法是POST方法。此程序包和GET方法方式相同地傳遞信息,但是,而不是將它作為一個文本字符串之後 ‘?’ 在URL中,它發送它作為一個單獨的消息。此消息來自標準輸入的CGI腳本的形式。
下麵是hello_post.cgi的腳本來處理Web瀏覽器所提供的輸入。這個腳本會處理GET和POST方法。
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $first_name = $FORM{first_name}; $last_name = $FORM{last_name}; #by wwww.gitbook.net print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title>Hello - Second CGI Program</title>"; print "</head>"; print "<body>"; print "<h2>Hello $first_name $last_name - Second CGI Program</h2>"; print "</body>"; print "</html>"; 1;
讓我們再次以上麵同樣的例子,通過使用HTML表單和提交按鈕的兩個值。我們將要使用CGI腳本hello_post.cgi,來處理這個輸入。
<FORM action="/cgi-bin/hello_post.cgi" method="POST"> First Name: <input type="text" name="first_name"> <br> Last Name: <input type="text" name="last_name"> <input type="submit" value="Submit"> </FORM>
這是上述表單的實際輸出,輸入第一個和最後一個名稱,然後單擊“提交”按鈕來查看結果。
複選框被使用時,須選擇一個以上的選項。
下麵是一個例子HTML代碼的表單與這兩個複選框。
<form action="/cgi-bin/checkbox.cgi" method="POST" target="_blank"> <input type="checkbox" name="maths" value="on"> Maths <input type="checkbox" name="physics" value="on"> Physics <input type="submit" value="Select Subject"> </form>
這段代碼的結果是下麵的表格。
下麵是checkbox.cgi腳本來處理網頁瀏覽器輸入單選按鈕。
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } if( $FORM{maths} ){ $maths_flag ="ON"; }else{ $maths_flag ="OFF"; } if( $FORM{physics} ){ $physics_flag ="ON"; }else{ $physics_flag ="OFF"; } #by www.gitbook.net print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title>Checkbox - Third CGI Program</title>"; print "</head>"; print "<body>"; print "<h2> CheckBox Maths is : $maths_flag</h2>"; print "<h2> CheckBox Physics is : $physics_flag</h2>"; print "</body>"; print "</html>"; 1;
單選按鈕用於當隻有一個選項是必需的以便進行選擇。
下麵是一個例子的兩個單選按鈕的HTML代碼:
<form action="/cgi-bin/radiobutton.cgi" method="POST" target="_blank"> <input type="radio" name="subject" value="maths"> Maths <input type="radio" name="subject" value="physics"> Physics <input type="submit" value="Select Subject"> </form>
下麵是radiobutton.cgi腳本來處理網頁瀏覽器輸入單選按鈕。
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $subject = $FORM{subject}; #by www.gitbook.net print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title>Radio - Fourth CGI Program</title>"; print "</head>"; print "<body>"; print "<h2> Selected Subject is $subject</h2>"; print "</body>"; print "</html>"; 1;
TEXTAREA元素用於多行文本時,要傳遞給CGI程序。
下麵是一個文本框的形式例如HTML代碼:
<form action="/cgi-bin/textarea.cgi" method="POST" target="_blank"> <textarea name="textcontent" cols=40 rows=4> Type your text here... </textarea> <input type="submit" value="Submit"> </form>
下麵是textarea.cgi腳本來處理Web瀏覽器所提供的輸入。
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $text_content = $FORM{textcontent}; #by www.gitbook.net print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title>Text Area - Fifth CGI Program</title>"; print "</head>"; print "<body>"; print "<h2> Entered Text Content is $text_content</h2>"; print "</body>"; print "</html>"; 1;
下拉框,當我們有很多可供選擇,但隻有一個或兩個將被選中。
這裡是一個下拉框的表單的HTML代碼示例:
<form action="/cgi-bin/dropdown.cgi" method="POST" target="_blank"> <select name="dropdown"> <option value="Maths" selected>Maths</option> <option value="Physics">Physics</option> </select> <input type="submit" value="Submit"> </form>
下麵是dropdown.cgi腳本來處理Web瀏覽器所提供的輸入。
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $subject = $FORM{dropdown}; print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title>Dropdown Box - Sixth CGI Program</title>"; print "</head>"; print "<body>"; print "<h2> Selected Subject is $subject</h2>"; print "</body>"; print "</html>"; 1;
HTTP協議是無狀態協議。但對於一個商業網站,它需要不同的頁麵之間維護會話信息。例如,一個用戶注冊結束後完成了許多網頁。但如何保持用戶的會話信息在所有的網頁。
在許多情況下,使用Cookie的記憶和跟蹤的喜好,購買,傭金是最有效的方法,更好的訪問者的體驗或網站的統計和其他所需的信息。
你的服務器發送一些數據到訪問者的瀏覽器的cookie的形式。瀏覽器可能會接受Cookie。如果是的話,它被存儲在訪問者的硬盤驅動器作為一個普通的文字記錄。現在,當訪問者到達您的網站的另一個頁麵上,cookie是可用於檢索。一旦檢索完畢,您的服務器知道/記憶存儲。
Cookies是一個純文本的5個可變長度字段的數據記錄:
Expires : cookie將到期的日期。如果是空白的,當訪問者退出瀏覽器,cookie將到期。
Domain : 您的網站的域名。
Path : 目錄或網頁設置cookie的路徑。這可能是空白的,如果你想從任何目錄或頁麵來檢索該cookie。
Secure : 如果此字段中包含單詞“安全”的cookie可能隻能與一個安全的服務器中檢索。如果該字段為空,不存在這樣的限製。
Name=Value : 這時候,Cookies設置鍵 - 值對的形式審查。
這是很容易將cookie發送到瀏覽器。這些cookies將被一起發送的HTTP頭。假設你要設置用戶名和密碼的cookie。因此,將做如下
#!/usr/bin/perl print "Set-Cookie:UserID=XYZ;\n"; print "Set-Cookie:Password=XYZ123;\n"; print "Set-Cookie:Expires=Tuesday, 31-Dec-2007 23:12:40 GMT";\n"; print "Set-Cookie:Domain=www.tutorialspoint.com;\n"; print "Set-Cookie:Path=/perl;\n"; print "Content-type:text/html\r\n\r\n"; ...........Rest of the HTML Content....
從這個例子中,你必須了解如何設置Cookie。我們使用的Set-Cookie HTTP標頭設置cookie。
在這裡它是可選的設置Cookie的屬性,如過期,域和路徑。值得注意的是,Cookie都設置在發送之前魔法線 "Content-type:text/html\r\n\r\n.
這是很容易檢索的所有設置Cookie。Cookie是存儲在CGI環境變量HTTP_COOKIE,他們將有以下的形式。
key1=value1;key2=value2;key3=value3....
下麵是一個例子,教你如何擷取Cookie。
#!/usr/bin/perl $rcvd_cookies = $ENV{'HTTP_COOKIE'}; @cookies = split /;/, $rcvd_cookies; foreach $cookie ( @cookies ){ ($key, $val) = split(/=/, $cookie); # splits on the first =. $key =~ s/^\s+//; $val =~ s/^\s+//; $key =~ s/\s+$//; $val =~ s/\s+$//; if( $key eq "UserID" ){ $user_id = $val; }elsif($key eq "Password"){ $password = $val; } } print "User ID = $user_id\n"; print "Password = $password\n"; This will produce following result User ID = XYZ Password = XYZ123
你會發現很多在互聯網上為您提供直接的功能,在你的CGI的程序中使用的內置模塊。以下是重要的鏈接。