




下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、CGI.基本原理CGI:通用網(wǎng)關(guān)接口(CommonGatewayInterface)是一個(gè)Web服務(wù)器主機(jī)提供信息服務(wù)的標(biāo)準(zhǔn)接口。通過CGI接口,Web服務(wù)器就能夠獲取客戶端提交的信息,轉(zhuǎn)交給服務(wù)器端的CGI程序進(jìn)行處理,最后返回結(jié)果給客戶端。組成CGI通信系統(tǒng)的是兩部分:一部分是html頁面,就是在用戶端瀏覽器上顯示的頁面。另一部分則是運(yùn)行在服務(wù)器上的Cgi程序。它們之間的通訊方式如下圖:服務(wù)器和客戶端之間的通信,是客戶端的瀏覽器和服務(wù)器端的http服務(wù)器之間的HTTP通信,我們只需要知道瀏覽器請求執(zhí)行服務(wù)器上哪個(gè)CGI程序就可以了,其他不必深究細(xì)節(jié),因?yàn)檫@些過程不需要程序員去操作。服務(wù)器和
2、CGI程序之間的通訊才是我們關(guān)注的。一般情況下,服務(wù)器和CGI程序之間是通過標(biāo)準(zhǔn)輸入輸出來進(jìn)行數(shù)據(jù)傳遞的,而這個(gè)過程需要環(huán)境變量的協(xié)作方可實(shí)現(xiàn)。1 .服務(wù)器將URL指向一個(gè)應(yīng)用程序2 .服務(wù)器為應(yīng)用程序執(zhí)行做準(zhǔn)備3 .應(yīng)用程序執(zhí)行,讀取標(biāo)準(zhǔn)輸入和有關(guān)環(huán)境變量4 .應(yīng)用程序進(jìn)行標(biāo)準(zhǔn)輸出對于Windows系統(tǒng)而言,還可以通過profile文件進(jìn)行數(shù)據(jù)傳輸(如ini文件),但在這里不做研究。環(huán)境變量在CGI中有著重要的地位!每個(gè)CGI程序只能處理一個(gè)用戶請求,所以在激活一個(gè)CGI程序進(jìn)程時(shí)也創(chuàng)建了屬于該進(jìn)程的環(huán)境變量。二.環(huán)境變量對于CGI程序來說,它繼承了系統(tǒng)的環(huán)境變量。CGI環(huán)境變量在CGI程序
3、啟動(dòng)時(shí)初始化,在結(jié)束時(shí)銷毀。當(dāng)一個(gè)CGI程序不是被HTTP服務(wù)器調(diào)用時(shí),它的環(huán)境變量幾乎是系統(tǒng)環(huán)境變量的復(fù)制。當(dāng)這個(gè)CGI程序被HTTP服務(wù)器調(diào)用時(shí),它的環(huán)境變量就會多了以下關(guān)于HTTP服務(wù)器、客戶端、CGI傳輸過程等項(xiàng)目。與請求相關(guān)的環(huán)境變量REQUEST_METHOD服務(wù)器與CGI程序之間的信息傳輸力式QUERY_STRING采用GET時(shí)所傳輸?shù)男畔ONTENT_LENGTHSTDIO中的有效信息長度CONTENT_TYPE指示所傳來的信息的MIME舊CONTENT_FILE使用WindowsHTTPd/WinCGI標(biāo)準(zhǔn)時(shí),用來傳送數(shù)據(jù)的文件名PATH_INFO路徑信息PATH_TRAN
4、SLATEDCGI程序的完整路徑名SCRIPT_NAME所調(diào)用的CGI程序的名字:與服務(wù)器相關(guān)的環(huán)境變量GATEWAY_INTERFACE服務(wù)器所實(shí)現(xiàn)的CGI版本SERVER_NAME服務(wù)器的IP或名字SERVER_PORT主機(jī)的端口號SERVER_SOFTWARE調(diào)用CGI程序的HTTP服務(wù)器的名稱和版本號與客戶端相關(guān)的環(huán)境變量REMOTE_ADDR客戶機(jī)的主機(jī)名REMOTE_HOST客戶機(jī)的IP地址ACCEPT例出能被次請求接受的應(yīng)答方式ACCEPT_ENCODING列出客戶機(jī)支持的編碼方式ACCEPT_LANGUAGE表明客戶機(jī)可接受語言的ISO代碼AUTORIZATION表明被證實(shí)了的
5、用戶FORM列出客戶機(jī)的EMAIL地址IF_MODIFIED_SINGCE當(dāng)用get方式請求并且只有當(dāng)文檔比指定日期更早時(shí)才返回?cái)?shù)據(jù)PRAGMA設(shè)定將來要用到的服務(wù)器代理REFFERER指出連接到當(dāng)前文檔的文檔的URLUSER_AGENT客戶端瀏覽器的信息CONTENT_TYPE:如application/x-www-form-urlencoded,表示數(shù)據(jù)來自HTML表單,并且經(jīng)過了URL編碼。ACCEPT:客戶機(jī)所支持的MIME類型清單,內(nèi)容如:"image/gif,image/jpegREQUEST_METHOD:它的值一般包括兩種:POST和GET,但我們寫CGI程序時(shí),最后
6、還要考慮其他的情況。1 .POST方法如果采用POST方法,那么客戶端來的用戶數(shù)據(jù)將存放在CGI進(jìn)程的標(biāo)準(zhǔn)輸入中,同時(shí)將用戶數(shù)據(jù)的長度賦予環(huán)境變量中的CONTENT_LENGTH??蛻舳擞肞OST方式發(fā)送數(shù)據(jù)有一個(gè)相應(yīng)的MIME類型(通用Internet郵件擴(kuò)充服務(wù):Multi-purposeInternetMailExtensions)。目前,MIME類型一般是:application/x-wwww-form-urlencoded,該類型表示數(shù)據(jù)來自HTML表單。該類型記錄在環(huán)境變量CONTENT_TYPE中,CGI程序應(yīng)該檢查該變量的值。2 .GET方法在該方法下,CGI程序無法直接從服務(wù)
7、器的標(biāo)準(zhǔn)輸入中獲取數(shù)據(jù),因?yàn)榉?wù)器把它從標(biāo)準(zhǔn)輸入接收到得數(shù)據(jù)編碼到環(huán)境變量QUERY_STRING(或PATH_INFO)。GET與POST的區(qū)別:采用GET方法提交HTML表單數(shù)據(jù)的時(shí)候,客戶機(jī)將把這些數(shù)據(jù)附加到由ACTION標(biāo)記命名的URL的末尾,用一個(gè)包括把經(jīng)過URL編碼后的信息與CGI程序的名字分開:有些程序員不愿意采用GET方法,因?yàn)樵谒麄兛磥?,把?dòng)態(tài)信息附加在URL的末尾有違URL的出發(fā)點(diǎn):URL作為一種標(biāo)準(zhǔn)用語,一般是用作網(wǎng)絡(luò)資源的唯一定位標(biāo)示。環(huán)境變量是一個(gè)保存用戶信息的內(nèi)存區(qū)。當(dāng)客戶端的用戶通過瀏覽器發(fā)出CGI請求時(shí),服務(wù)器就尋找本地的相應(yīng)CGI程序并執(zhí)行它。在執(zhí)行CGI程序
8、的同時(shí),服務(wù)器把該用戶的信息保存到環(huán)境變量里。接下來,CGI程序的執(zhí)行流程是這樣的:查詢與該CGI程序進(jìn)程相應(yīng)的環(huán)境變量:第一步是request_method,如果是POST,就從環(huán)境變量的len,然后到該進(jìn)程相應(yīng)的標(biāo)準(zhǔn)輸入取出len長的數(shù)據(jù)。如果是GET,則用戶數(shù)據(jù)就在環(huán)境變量的QUERY_STRING里。3 .POST與GET的區(qū)別以GET方式接收的數(shù)據(jù)是有長度限制,而用POST方式接收的數(shù)據(jù)是沒有長度限制的。并且,以GET方式發(fā)送數(shù)據(jù),可以通過URL的形式來發(fā)送,但POST方式發(fā)送的數(shù)據(jù)必須要通過Form才到發(fā)送。三.CGI程序?qū)崿F(xiàn)步驟1 .從服務(wù)器獲取數(shù)據(jù)C語言實(shí)現(xiàn)代碼:#includ
9、e<stdio.h>#include<stdlib.h>#include<string.h>intget_inputs()(intlength;char*method;char*inputstring;method=getenv(REQUEST_METHOD");將返回結(jié)果賦予指針if(method=NULL)return1;找不到環(huán)境變量REQUEST_METHODif(!strcmp(method,"POST")/POST方法(length=atoi(getenv(CONTENT_LENGTH");結(jié)果是字符,需要
10、轉(zhuǎn)換if(length!=0)(inputstring=malloc(sizeof(char)*length+1)/必須申請緩存,因?yàn)閟tdin是不帶緩存的。fread(inputstring,sizeof(char),length,stdin);/從標(biāo)準(zhǔn)輸入讀取一定數(shù)據(jù))elseif(!strcmp(method,GET")(Inputstring=getenv(QUERY_STRING");length=strlen(inputstring);)if(length=0)return0;)Perl實(shí)現(xiàn)代碼:$method=$ENV,REQUEST_METHOD?;if($
11、methodeq,POST?Read(STDIN,$input,$ENV,CONTENT_LENGTH?);)if($methodeq,GET?|$methodeq,HEAD?)$input=$ENV,QUERY_STRING今)if($inputeq")'&print_form;exit;PYTHON代碼實(shí)現(xiàn)#!/usr/local/bin/pythonimportcgidefmain():form=cgi.FieldStorage()Python代碼實(shí)現(xiàn)更簡單,cgi.FieldStorage()返回一個(gè)字典,字典的每一個(gè)key就是變量名,key對應(yīng)的值就是變量名
12、的值,更本無需用戶再去進(jìn)行數(shù)據(jù)解碼!獲取環(huán)境變量的時(shí)候,如果先判斷“REQUEST_METHOD”是否存在,程序會更健壯,否則在某些情況下可能會造成程序崩潰。因?yàn)榧偃鬋GI程序不是由服務(wù)器調(diào)用的,那么環(huán)境變量集里就沒有與CGI相關(guān)的環(huán)境變量(如REQUEST_METHOD,REMOTE_ADDR等)添加進(jìn)來,也就是說“getenv(REQUEST_METHOD")”將返回NULL!2 .URL編碼不管是POST還是GET方式,客戶端瀏覽器發(fā)送給服務(wù)器的數(shù)據(jù)都不是原始的用戶數(shù)據(jù),而是經(jīng)過URL編碼的。此時(shí),CGI的環(huán)境變量Content_type將被設(shè)置,如Content_type=a
13、pplication/x-www-form-urlencode就表示服務(wù)器收到的是經(jīng)過URL編碼的包含有HTML表單變量數(shù)據(jù)。編碼的基本規(guī)則是:變量之間用“&”分開;變量與其對應(yīng)值用“=”連接;空格用“+”代替;保留的控制字符則用“”連接對應(yīng)的16禁止ASCII碼代替;某些具有特殊意義的字符也用“”接對應(yīng)的16進(jìn)制ASCII碼代替;空格是非法字符;任意不可打印的ASCII控制字符均為非法字符。例如,假設(shè)3個(gè)HTML表單變量filename、e-mail和comments,它們的值對應(yīng)分別為hello、mike和I?lbethereforyou,貝U經(jīng)過URL編碼后應(yīng)為:filename
14、=hello&e-mail=hello&comments=I%27ll+be+there+for+you所以,CGI程序從標(biāo)準(zhǔn)輸入或環(huán)境變量中獲取客戶端數(shù)據(jù)后,還需要進(jìn)行解碼。解碼的過程就是URL編碼的逆變:根據(jù)"&”和“="分離HTML表單變量,以及特殊字符的替換。在解碼方面,PYTHON代碼實(shí)現(xiàn)是最理想的,cgi.FieldStorage()函數(shù)在獲取數(shù)據(jù)的同時(shí)就已自動(dòng)進(jìn)行代碼轉(zhuǎn)換了,無需程序員再進(jìn)行額外的代碼編寫。Perl其次,因?yàn)樵谝粋€(gè)現(xiàn)成的Perl庫:cgi-lib.pl中提供了ReadParse函數(shù),用它來進(jìn)行URL解碼很簡單:requi
15、re,cgi-lib.pl?&ReadParse(*input);3 .CGI數(shù)據(jù)輸出CGI程序如何將信息處理結(jié)果返回給客戶端?這實(shí)際上是CGI格式化輸出。在CGI程序中的標(biāo)準(zhǔn)輸出stdout是經(jīng)過重定義了的,它并沒有在服務(wù)器上產(chǎn)生任何的輸出內(nèi)容,而是被重定向到客戶瀏覽器,這與它是由C,還是Perl或Python實(shí)現(xiàn)無關(guān)。所以,我們可以用打印來實(shí)現(xiàn)客戶端新的HTML頁面的生成。比如,C的printf是向該進(jìn)程的標(biāo)準(zhǔn)輸出發(fā)送數(shù)據(jù),Perl和Python用print向該進(jìn)程的標(biāo)準(zhǔn)輸出發(fā)送數(shù)據(jù)。(1) CGI標(biāo)題CGI的格式輸出內(nèi)容必須組織成標(biāo)題/內(nèi)容的形式。CGI標(biāo)準(zhǔn)規(guī)定了CGI程序可以使
16、用的三個(gè)HTTP標(biāo)題。標(biāo)題必須占據(jù)第一行輸出!而且必須隨后帶有一個(gè)空行。標(biāo)題描述Content_type(內(nèi)容類型)設(shè)定隨后輸出數(shù)據(jù)所用的MIME類型Location(地址)設(shè)定輸出為另外一個(gè)文檔(URL)Status(狀態(tài))指定HIIP狀態(tài)碼MIME:向標(biāo)準(zhǔn)輸出發(fā)送網(wǎng)頁內(nèi)容時(shí)要遵守MIME格式規(guī)則:任意輸出前面必須有一個(gè)用于定義MIME類型的輸出內(nèi)容(Content-type)行,而且隨后還必須跟一個(gè)空行。如果遺漏了這一條,服務(wù)將會返回一個(gè)錯(cuò)誤信息。(同樣使用于其他標(biāo)題)例如Perl和Python:printContent-type:text/htmlnn"輸出HTML格式的數(shù)據(jù)p
17、rint<body>welcome<br>"print</body>"Cprintf(Content-type:text/htmlnn”)printf(Welcomen");MIME類型以類型/子類型(type/subtype)的形式表示。其中type表示一下幾種典型文件格式的一種:Text、Audio、Video、Image、Application>Mutipart、MessageSubtype則用來描述具體所用的數(shù)據(jù)格式。Application/msword微軟的Word文件Application/octet-stre
18、am一種通用的二進(jìn)制文件格式Application/zipZip壓縮文件Application/pdfPdf文件oooooooooooooooooooooooooo0000000000000000000000000Location:使用Location標(biāo)題,一個(gè)CGI可以使當(dāng)前用戶轉(zhuǎn)而訪問同一服務(wù)器上的另外一個(gè)程序,甚至可以訪問另外一個(gè)URL,但服務(wù)器對他們的處理方式不一樣。使用Location的格式為:Location:Filename/URL,例如:printLocation:/test.htmlnn"這與直接鏈接到test.html的效果是一樣的。printLocation:h
19、ttp:由于該URL并不指向當(dāng)前服務(wù)器,用戶瀏覽器并不會直接鏈接到指定的URL,而是給用戶輸出提示信息。HTTP狀態(tài)碼:表示了請求的結(jié)果狀態(tài),是CGI程序通過服務(wù)器用來通知用戶其請求是否成功執(zhí)行的信息碼,本文不做研究。四.CGI中的信號量和文件鎖因?yàn)镃GI程序時(shí)公用的,而WEB服務(wù)器都支持多進(jìn)程運(yùn)行,因此可能會發(fā)生同時(shí)有多個(gè)用戶訪問同一個(gè)CGI程序的情況。比如,有2個(gè)用戶幾乎同時(shí)訪問同一個(gè)CGI程序,服務(wù)器為他們創(chuàng)建了2個(gè)CGI程序進(jìn)程,設(shè)為進(jìn)程A和進(jìn)程B。假如進(jìn)程A首先打開了某個(gè)文件,然后由于某種原因被掛起(一般是由于操作系統(tǒng)的進(jìn)程調(diào)度);而就在進(jìn)程A被掛起的這段時(shí)間內(nèi),進(jìn)程B完成了對文件的
20、整個(gè)操作流程:打開,寫入,關(guān)閉;進(jìn)程A再繼續(xù)往下執(zhí)行,但進(jìn)程A所操作的文件依舊是原來文件的就版本,此時(shí)進(jìn)程A的操作結(jié)果將覆蓋進(jìn)程B的操作結(jié)果。為了防止這種情況發(fā)生,需要用到文件鎖或者信號量。鑰匙文件?假如有多個(gè)不同的HTML可以調(diào)用同一個(gè)CGI程序,那么CGI程序如何區(qū)分它們呢?一個(gè)是通過隱含的INPUT標(biāo)簽。不過覺得這個(gè)比較麻煩,因?yàn)镃GI必須經(jīng)過一系列解碼后才能找到這個(gè)隱含INPUT的變量和其值。五.設(shè)置HTTP服務(wù)器以兼容CGI用Perl編寫的CGI程序后綴為:.pl;Python編寫的CGI程序后綴為:.py;而C編寫的CGI程序后綴為:.cgi,如果在win下編譯出來的是.exe,最
21、好將它重命名為.cgi。這些都是為了HTTP服務(wù)能夠識別并調(diào)用它們。當(dāng)使用appchehttpd服務(wù)器時(shí),請編輯它的配置文件httpd.conf如下:修改AddHandlercgi-script一句為AddHandlercgi-script.cgi.py.pl六.關(guān)于CGI的C語言庫cgihtmlCgihtml是一個(gè)應(yīng)用非常廣泛的C語言編寫的CGI庫。它提供的功能函數(shù)如下:Read_cgi_input():獲取并解析HTML表單輸入,返回一個(gè)指向某結(jié)構(gòu)體的指針Cgi_val():獲取每個(gè)表單變量的值Html_header():輸出HTML標(biāo)題欄Html_begin():輸出HTML文檔的開始部
22、分H1():輸出一行字符,字體為H1Html_end():輸出HTML文檔的結(jié)尾部分。#includecgi-lib.h"#includehtml-lib.h"#includestring-lib.h"六.后話有的人認(rèn)為可以用JavaScript來代替CGI程序,這其實(shí)是一個(gè)概念上的錯(cuò)誤。JavaScript只能夠在客戶瀏覽器中運(yùn)行,而CGI卻是工作在服務(wù)器上的。他們所做的工作有一些交集,比如表單數(shù)據(jù)驗(yàn)證一類的,但是JavaScript是絕對無法取代CGI的。但可以這樣說,如果一項(xiàng)工作即能夠用JavaScript來做,又可以用CGI來做,那么絕對要使用JavaSc
23、ript,在執(zhí)行的速度上,JavaScript比CGI有著先天的優(yōu)勢。只有那些在客戶端解決不了的問題,比如和某個(gè)遠(yuǎn)程數(shù)據(jù)庫交互,這時(shí)就應(yīng)該使用CGI了。SSI:一種用來動(dòng)態(tài)輸出HTML文本的特殊程序。網(wǎng)頁里包含有某個(gè)變量,提交給服務(wù)器后,只有該變量改變。此時(shí)我們希望服務(wù)器不要把整個(gè)頁面內(nèi)容都發(fā)送過來,而只需要告訴客戶端的瀏覽器,哪個(gè)變量的值便成什么樣了,瀏覽器會自動(dòng)更新。SSI在服務(wù)器端運(yùn)行。SSI不需要外部接口,它不像CGI從標(biāo)準(zhǔn)輸入接收信息。你瀏覽你的HTML文檔時(shí)看不到SSI標(biāo)記,因?yàn)樗呀?jīng)被相應(yīng)的程序輸出所替代。所有的SSI命令都是嵌入在普通的HTML注釋行中的。當(dāng)服務(wù)器無法解釋SSI
24、時(shí),它將不解釋并直接把文檔傳給瀏覽器,由于命令在注釋中,故瀏覽器將忽略它們。而當(dāng)服務(wù)器識別SSI時(shí),它并不將該命令傳給瀏覽器,相反,服務(wù)器將從上到下掃描HTML文檔,執(zhí)行每一個(gè)嵌入注釋的命令,并將命令的執(zhí)行結(jié)果代替原注釋。<!注釋文本->。服務(wù)器將根本不查看注釋,除非已啟動(dòng)SSI。與純注釋不同的是,所有的SSI命令都是以#打頭。<!-#commandtagname=parameter"->,command指出服務(wù)器做什么,tagname指出參數(shù)類型,parameter是該命令的用戶定義值。Thecurrentdateis<!-#echovar=DATE.LOCAL”->,服務(wù)器將向?yàn)g覽器輸出時(shí)間。AtypicalHTMLformYou-rirstname:You"lastncme:Clic<heretosjbmtform:c|<formmethod=I,POST,1action=H<p>Yourfirstname:inputtype="text1'name=,firstname,><p>Yourlastname:<inputtype=",texu,name=",lastname,&g
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 綏化智能小區(qū)管理辦法
- 繼續(xù)教育學(xué)院管理辦法
- 育嬰師職業(yè)道德培訓(xùn)課件
- 肩周炎中醫(yī)講座課件
- 機(jī)房安全管理培訓(xùn)課件
- 復(fù)印五年級數(shù)學(xué)試卷
- 阜陽一模高三數(shù)學(xué)試卷
- 東營三模高考數(shù)學(xué)試卷
- 高三五調(diào)數(shù)學(xué)試卷
- 高起本高等數(shù)學(xué)試卷
- 2025年廣西中考語文試題卷(含答案)
- 2025年南京市中考數(shù)學(xué)真題試卷
- 2024年深圳市中考?xì)v史試卷真題(含答案解析)
- 基礎(chǔ)會計(jì)教材電子版
- 四川省地質(zhì)災(zāi)害治理工程常用資料表格
- 患者隱私保護(hù)課件
- RFJ0132010人民防空工程防化設(shè)計(jì)規(guī)范
- CA6140車床杠桿工藝設(shè)計(jì)說明書完全版
- T_CHES 17-2018 水井報(bào)廢與處理技術(shù)導(dǎo)則
- 酒店住宿賬單模板
- 餐飲服務(wù)員必備六大技能課程
評論
0/150
提交評論