當前位置:首頁 » Perl » Perl CGI

Perl CGI

Perl CGI教學,CGI是什麼? 學習例子,實例代碼,CGI教學等

CGI是什麼 ?

  • 通用網關接口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編程之前,請確保您的Web服務器支持CGI,它被配置為處理CGI程序。由HTTP服務器來執行所有的CGI程序保持在一個預先配置的目錄。此目錄被稱為CGI目錄,並按照約定,它被命名為/cgi-bin目錄。通過慣例的PERL CGI文件擴展名為.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。

HTTP頭

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程序,將有機會獲得以下環境變量。這些變量中發揮了重要作用,當在編寫任何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");
}

GET 和 POST 方法

可能所遇到的有很多情況,如,你需要從您的瀏覽器傳遞一些信息到Web服務器並最終到達CGI程序。最常見的瀏覽器使用兩種方法將此信息傳遞到Web服務器。這些方法是GET方法和POST方法。

使用GET方法傳遞信息:

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: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;

簡單表單舉例:GET方法

下麵是一個簡單的例子,通過兩個值,使用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>

這是上述表單輸入第一個和最後一個名稱,然後單擊“提交”按鈕來查看結果。


使用POST方法傳遞信息:

一般信息傳遞給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>

這是上述表單的實際輸出,輸入第一個和最後一個名稱,然後單擊“提交”按鈕來查看結果。


將複選框資料傳遞給CGI程序

複選框被使用時,須選擇一個以上的選項。

下麵是一個例子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;

單選按鈕傳遞數據到CGI程序

單選按鈕用於當隻有一個選項是必需的以便進行選擇。

下麵是一個例子的兩個單選按鈕的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;

通過CGI程序的文本區域的數據

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;

通過下拉框中的數據CGI程序

下拉框,當我們有很多可供選擇,但隻有一個或兩個將被選中。

這裡是一個下拉框的表單的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;

使用CGI Cookie

HTTP協議是無狀態協議。但對於一個商業網站,它需要不同的頁麵之間維護會話信息。例如,一個用戶注冊結束後完成了許多網頁。但如何保持用戶的會話信息在所有的網頁。

在許多情況下,使用Cookie的記憶和跟蹤的喜好,購買,傭金是最有效的方法,更好的訪問者的體驗或網站的統計和其他所需的信息。

它如何工作

你的服務器發送一些數據到訪問者的瀏覽器的cookie的形式。瀏覽器可能會接受Cookie。如果是的話,它被存儲在訪問者的硬盤驅動器作為一個普通的文字記錄。現在,當訪問者到達您的網站的另一個頁麵上,cookie是可用於檢索。一旦檢索完畢,您的服務器知道/記憶存儲。

Cookies是一個純文本的5個可變長度字段的數據記錄:

  • Expires : cookie將到期的日期。如果是空白的,當訪問者退出瀏覽器,cookie將到期。

  • Domain : 您的網站的域名。

  • Path : 目錄或網頁設置cookie的路徑。這可能是空白的,如果你想從任何目錄或頁麵來檢索該cookie。

  • Secure : 如果此字段中包含單詞“安全”的cookie可能隻能與一個安全的服務器中檢索。如果該字段為空,不存在這樣的限製。

  • Name=Value : 這時候,Cookies設置鍵 - 值對的形式審查。

設置Cookie

這是很容易將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。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模塊和庫

你會發現很多在互聯網上為您提供直接的功能,在你的CGI的程序中使用的內置模塊。以下是重要的鏈接。