WEB開發(fā)技術(shù)-第四章-CGI編程原理_第1頁
WEB開發(fā)技術(shù)-第四章-CGI編程原理_第2頁
WEB開發(fā)技術(shù)-第四章-CGI編程原理_第3頁
WEB開發(fā)技術(shù)-第四章-CGI編程原理_第4頁
WEB開發(fā)技術(shù)-第四章-CGI編程原理_第5頁
已閱讀5頁,還剩59頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

第四章CGI編程原理HTTP原理CGI的基礎(chǔ)知識CGI的工作原理CGI編程HTTP概要超文本傳輸協(xié)議HTTP(HypertextTransportProtocol)是Web瀏覽器與Web服務(wù)器之間進行數(shù)據(jù)傳輸?shù)膽?yīng)用層通信協(xié)議,它建立在TCP/IP協(xié)議的基礎(chǔ)上,用以傳輸超文本文檔(它是網(wǎng)絡(luò)上最主要的資源)。2/69基于HTTP協(xié)議的客戶/服務(wù)器模式的信息交換過程,它分四個過程:建立連接、發(fā)送請求信息、發(fā)送響應(yīng)信息、關(guān)閉連接。在WWW中,“客戶”與“服務(wù)器”是一個相對的概念,只存在于一個特定的連接期間,即在某個連接中的客戶在另一個連接中可能作為服務(wù)器。HTTP原理3/69HTTP在TCP/IP協(xié)議族中的位置TCP/IP模型TCP/IP參考模型是4層結(jié)構(gòu):網(wǎng)絡(luò)接口層:也稱數(shù)據(jù)鏈路層,通常包括操作系統(tǒng)中的設(shè)備驅(qū)動程序和計算機中的網(wǎng)卡,一起處理與電纜(或其他任何傳輸媒介)的物理接口細節(jié)互聯(lián)網(wǎng)層:也稱網(wǎng)絡(luò)層,其作用是處理分組在網(wǎng)絡(luò)中的活動,例如分組的選路。在TCP/IP協(xié)議族中,網(wǎng)絡(luò)層協(xié)議包括IP協(xié)議(網(wǎng)際協(xié)議),ICMP協(xié)議(互聯(lián)網(wǎng)控制報文協(xié)議),以及IGMP協(xié)議(互聯(lián)組管理協(xié)議)4/69TCP/IP模型傳輸層:主要為兩臺主機上的應(yīng)用程序提供端到端的通信。在TCP/IP協(xié)議族中,有兩個互不相同的傳輸協(xié)議:TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報協(xié)議)。TCP為兩臺主機提供高可靠性的數(shù)據(jù)通信,UDP則為應(yīng)用層提供一種低可靠的簡單服務(wù)。5/69TCP/IP模型應(yīng)用層:包括所有的高層協(xié)議。早期的應(yīng)用層有遠程登錄協(xié)議(telnet)、文件傳輸協(xié)議(FTP)和簡單郵件傳輸協(xié)議(SMTP)等協(xié)議。最近幾年出現(xiàn)了一些新的應(yīng)用層協(xié)議,如用于將網(wǎng)絡(luò)中的主機的名字地址映射成網(wǎng)絡(luò)地址的域名服務(wù)(DNS),用于傳輸網(wǎng)絡(luò)新聞的協(xié)議(NNTP)和用于從WWW網(wǎng)上讀取頁面信息的超文本傳輸協(xié)議(HTTP)等。6/69HTTP協(xié)議基于請求/響應(yīng)模式(相當(dāng)于C/S)一個客戶機與服務(wù)器建立連接后,發(fā)送一個請求給服務(wù)器,請求方式的格式為:統(tǒng)一資源標(biāo)識符(URL)、協(xié)議版本號,后邊是MIME(多用途的網(wǎng)際郵件擴充協(xié)議)信息,包括請求修飾符、客戶機信息和可能的內(nèi)容服務(wù)器接到請求后,給予相應(yīng)的響應(yīng)信息,其格式為一個狀態(tài)行,包括信息的協(xié)議版本號、一個成功或錯誤的代碼,后邊是MIME信息,包括服務(wù)器信息、實體信息和可能的內(nèi)容7/698/69MIME意為多目的Internet郵件擴展(MultipurposeInternetMailExtensions),它設(shè)計的最初目的是為了在發(fā)送電子郵件時附加多媒體數(shù)據(jù),讓郵件客戶程序能根據(jù)其類型進行處理。每個MIME類型由兩部分組成,前面是數(shù)據(jù)的大類別,例如聲音audio、圖象image等,后面定義具體的種類。

常見的MIME類型:

超文本標(biāo)記語言文本.htm,.html text/html普通文本.txt text/plainRTF文本.rtf application/rtfGIF圖形.gif image/gifJPEG圖形.ipeg,.jpg image/jpegau聲音文件.au audio/basicMIDI音樂文件mid,.midi audio/midi,audio/x-midiRealAudio音樂文件.ra,.ram audio/x-pn-realaudioMPEG文件.mpg,.mpeg video/mpegAVI文件.avi video/x-msvideoGZIP文件.gz application/x-gzipTAR文件.tar application/x-tar

返回9/69富文本格式(RichTextFormat,RTF)是一種文件格式,它使你能在不同的操作系統(tǒng)下的不同的文字處理軟件間更換文本文件。比如,你可以在Windows98下用MicrosoftWord創(chuàng)建一個文件,把它存為RTF文件(文件名后綴為“.rtf”),然后你可以將文件發(fā)給一個在Windows3.1下使用WordPerfect6.0的人,他是可以打開這個文件閱讀它的。(在某些情況下,RTF性能可以被做到文字處理軟件中。而在其他情況下可能需要一個獨立的閱讀器或編輯器。)10/69HTTP工作原理示意圖11/69瀏覽器服務(wù)器發(fā)出請求返回HTML文檔HTTP12/69HTTP原理詳解一個客戶端應(yīng)用(如Web瀏覽器)打開到Web服務(wù)器的HTTP端口的一個“套接字”(缺省為80)。

例如:http://localhost:8080/internet4.htmlHTTP規(guī)范:Internet工程制定組織(IETF)發(fā)布的RFC指定Internet標(biāo)準(zhǔn)。RFC:RequestForComments的簡稱,是Internet的標(biāo)準(zhǔn)(草案),多是一些技術(shù)標(biāo)準(zhǔn)文檔,可在/rfc.htm找到。大多數(shù)的網(wǎng)絡(luò)協(xié)議最初都是以RFC文檔發(fā)布的,最終確立為協(xié)議。RFC用編號來區(qū)分。HTTP的幾個重要RFC:

RFC1945

HTTP

1.0

描述

RFC2068

HTTP

1.1

初步描述

RFC2616

HTTP

1.1

標(biāo)準(zhǔn)資源標(biāo)識符URI(Uniform

Resource

Identifter,URI)1.連接至Web服務(wù)器13/69注:1)套接字(Socket)是IP地址和端口的組合,用于進行網(wǎng)絡(luò)通訊,任何應(yīng)用程序需要和網(wǎng)絡(luò)上的其他應(yīng)用程序進行通信時,必須具有相應(yīng)的套接字,例如Web站點偵聽客戶的HTTP請求,那么它就綁定在相應(yīng)的套接字(IP地址和端口,例如端口為標(biāo)準(zhǔn)的TCP80)上。2)TCP層用端口號來區(qū)別不同的會話。用戶程序通常使用或多或少的隨機產(chǎn)生的端口號,特定的端口號被指派給等待請求的程序。14/69通過連接,客戶端寫一個ASCII文本請求行,后跟0或多個HTTP頭標(biāo),一個空行和實現(xiàn)請求的任意數(shù)據(jù)。一個請求由四個部分組成:請求行、請求頭標(biāo)、空行和請求數(shù)據(jù)。2.發(fā)送HTTP請求1)請求行由三個標(biāo)記組成:請求方法、請求URI和HTTP版本,它們用空格分隔。

例如:GET/index.htmlHTTP/1.1HOST:兩次回車發(fā)送請求(用telnet做實驗)15/69HTTP規(guī)范定義了8種可能的請求方法:GET

檢索URI中標(biāo)識資源的一個簡單請求HEAD

與GET方法相同,服務(wù)器只返回狀態(tài)行和頭標(biāo),并不返回請求文檔POST

服務(wù)器接受被寫入客戶端輸出流中的數(shù)據(jù)的請求PUT

服務(wù)器保存請求數(shù)據(jù)作為指定URI新內(nèi)容的請求DELETE

服務(wù)器刪除URI中命名的資源的請求OPTIONS

關(guān)于服務(wù)器支持的請求方法信息的請求TRACE

Web服務(wù)器反饋Http請求和其頭標(biāo)的請求CONNECT

已文檔化但當(dāng)前未實現(xiàn)的一個方法,預(yù)留做隧道處理16/692)請求頭標(biāo)由“關(guān)鍵字:值”對組成,每行一對,關(guān)鍵字和值用冒號(:)分隔。請求頭標(biāo)通知服務(wù)器有關(guān)于客戶端的功能和標(biāo)識,典型的請求頭標(biāo)有:

User-Agent

客戶端廠家和版本

Accept

客戶端可識別的內(nèi)容類型列表

Content-Length

附加到請求的數(shù)據(jù)字節(jié)數(shù)

3)空行最后一個請求頭標(biāo)之后是一個空行,發(fā)送回車符和退行,通知服務(wù)器以下不再有頭標(biāo)。

4)請求數(shù)據(jù)使用POST傳送數(shù)據(jù),最常使用的是Content-Type和Content-Length頭標(biāo)。17/69Web服務(wù)器解析請求,定位指定資源。服務(wù)器將資源副本寫至套接字,在此處由客戶端讀取。一個響應(yīng)由四個部分組成;狀態(tài)行、響應(yīng)頭標(biāo)、空行、響應(yīng)數(shù)據(jù)。1)狀態(tài)行由三個標(biāo)記組成:HTTP版本、響應(yīng)代碼和響應(yīng)描述。

HTTP版本:向客戶端指明其可理解的最高版本。響應(yīng)代碼:3位的數(shù)字代碼,指出請求的成功或失敗,如果失敗則指出原因。HTTP響應(yīng)碼:

1xx:信息,請求收到,繼續(xù)處理

2xx:成功,行為被成功地接受、理解和采納

3xx:重定向,為了完成請求,必須進一步執(zhí)行的動作

4xx:客戶端錯誤響應(yīng)描述:為響應(yīng)代碼的可讀性解釋。例如:HTTP/1.1

200

OK3.服務(wù)端接受請求并返回HTTP響應(yīng)18/691)瀏覽器首先解析狀態(tài)行,查看表明請求是否成功的狀態(tài)代碼2)然后解析每一個響應(yīng)頭標(biāo),頭標(biāo)告知HTML的位置3)讀取響應(yīng)數(shù)據(jù)HTML,根據(jù)HTML的語法和語義對其進行格式化,并在瀏覽器窗口中顯示它4)一個HTML文檔可能包含其它需要被載入的資源引用,瀏覽器識別這些引用,對其它的資源再進行額外的請求,此過程循環(huán)多次。2)響應(yīng)頭標(biāo):像請求頭標(biāo)一樣,它們指出服務(wù)器的功能,標(biāo)識出響應(yīng)數(shù)據(jù)的細節(jié)3)空行:最后一個響應(yīng)頭標(biāo)之后是一個空行,發(fā)送回車符和退行,表明服務(wù)器以下不再有頭標(biāo)4)響應(yīng)數(shù)據(jù):HTML文檔和圖像等,也就是HTML本身無狀態(tài)連接:HTTP模型是無狀態(tài)的,在處理一個請求時,Web服務(wù)器并不記住來自同一客戶端的請求。4.服務(wù)器關(guān)閉連接,瀏覽器解析響應(yīng)19/6920/69HTTP的無狀態(tài)特點HTTP協(xié)議的目的:支持超文本的傳輸支持資源的傳輸:發(fā)送請求和響應(yīng)請求的過程客戶端和服務(wù)器誰需要記錄?一般而言:一個URL對應(yīng)著唯一的超文本無論對誰,HTTP服務(wù)器都會根據(jù)接收到的URL請求返回相同的超文本該唯一性使得記錄用戶的行為狀態(tài)變得毫無意義所以,HTTP協(xié)議被設(shè)計為無狀態(tài)的連接協(xié)議符合它本身的需求。21/69

既然HTTP協(xié)議的目的在于支持超文本的傳輸,更加廣義一些就是支持資源的傳輸,那么在客戶端瀏覽器向HTTP服務(wù)器發(fā)送請求,繼而HTTP服務(wù)器將相應(yīng)的資源發(fā)回給客戶端這樣一個過程中,無論對于客戶端還是服務(wù)器,都沒有必要記錄這個過程,因為每一次請求和響應(yīng)都是相對獨立的,就好像你在自動售貨機前投下硬幣購買商品一樣,誰都不會也不需要記住這樣一個交易過程。一般而言,一個URL對應(yīng)著唯一的超文本,而HTTP服務(wù)器也絕對公平公正,不管你是Michael,還是Jordon,它都會根據(jù)接收到的URL請求返回相同的超文本。正是因為這樣的唯一性,使得記錄用戶的行為狀態(tài)變得毫無意義CGI的概念及功能CGI是CommonGatewayInterface的縮寫,即通用網(wǎng)關(guān)接口。它是Web服務(wù)器的一部分,是外部擴展程序與WWW服務(wù)器交互的一個標(biāo)準(zhǔn)接口。按照CGI標(biāo)準(zhǔn)編寫的外部擴展應(yīng)用程序可以處理客戶端輸入的需要協(xié)同工作的數(shù)據(jù),完成客戶端與服務(wù)器的交互操作。通俗地說,CGI是一個運行在WWW服務(wù)器上,提供同客戶端HTML頁面接口的軟件包。CGI的主要功能是在WWW環(huán)境下,提供客戶端HTML頁面接口,使客戶與網(wǎng)頁作者之間產(chǎn)生互動作用。CGI加入到WWW中,使得WWW的環(huán)境不僅有單向的信息瀏覽,更有雙向的信息交流。22/69CGI的基礎(chǔ)知識通過CGI,Web服務(wù)器可以調(diào)用(激活)一個程序,同時將用戶提交的數(shù)據(jù)傳給這個程序,隨后,又將該程序的響應(yīng)(輸出)返回給瀏覽器。

23/69CGI的特點及運行環(huán)境CGI的特點:CGI程序可以用任何語言編寫,可以在任何平臺上開發(fā),而且無須做太大的修改就可以在不同的平臺間移植。CGI的主要運行環(huán)境有:WIN95/98/2000/NT/XP;UNIX;LINUX等。CGI運行的服務(wù)器主要有:

IIS;Sambar;ApacheWeb;OmniHTTPd服務(wù)器等。24/69CGI的調(diào)用方式CGI程序調(diào)用方式

1)通過URL直接調(diào)用。在瀏覽器的URL欄里直接寫入程序的地址就可以調(diào)用該程序。

如:“82/cgi-win/cgiprogram.exe”2)通過交互式主頁里的FORM欄調(diào)用,通常都是用戶在填完一張輸入信息主頁后按“確認(rèn)”按鈕啟動CGI程序。

系統(tǒng)設(shè)置1)IIS中要設(shè)置CGI目錄的屬性(XP):我的電腦-管理-服務(wù)和應(yīng)用程序-Internet信息服務(wù)-網(wǎng)站-(默認(rèn)網(wǎng)站)-屬性:主目錄-執(zhí)行權(quán)限-腳本和可執(zhí)行文件

2)Win2003:Web服務(wù)擴展-CGI擴展(允許)

3)C語言得到的exe文件可能需要把后綴改為”.cgi”25/69CGI的編程語言CGI的編程(腳本)語言有:Perl、TCL;C/C++、VisualBasic;JavaScript、VBScript、VisualJava++、Java;Fortran、Pascal、Delphi等等。解釋型腳本語言,是一種不需要預(yù)先編譯的語言,它完全依賴解釋器來完成任務(wù)。其語言通俗易學(xué),能夠被廣泛應(yīng)用。缺點:因其源代碼是ASCII碼的文本文件,用戶能夠看到腳本,所以安全性較差。由于它都是在執(zhí)行的時候才能進行解釋,所以執(zhí)行效率比較低。(例如Perl和TCL)編譯型腳本語言,是一種需要預(yù)先編譯、能夠生成二進制代碼的語言。由于其需要編譯環(huán)境,所以它依賴于具體的操作平臺,但是這種語言可以降低因裝載解釋器造成的服務(wù)器負載過量,同時,由于其生成的是二進制代碼,所以安全性較高(例如C/C++)26/69解釋型腳本語言Perl是近年來使用較廣泛的CGI腳本語言之一。其前身是屬于UNIX專用的高級語言,本身具有強大的字符串處理能力。Perl最大的特點是可以用在各種OS系統(tǒng)服務(wù)器平臺上,并且可以免費從Internet網(wǎng)上下載。TCL是正在發(fā)展之中的CGI腳本語言,其主要用于Unix系統(tǒng)的服務(wù)器上,要求用戶懂C語言,基本上可以說TCL是C語言程序的一個庫。27/69返回編譯型腳本語言C和C++是目前較為流行的CGI腳本語言,其語義簡潔、緊湊,使用方便靈活,執(zhí)行速度快。由于它們的運算符和數(shù)據(jù)結(jié)構(gòu)豐富,所以它們具有相當(dāng)強大的功能。C和C++在各種OS服務(wù)器平臺上都可以移植,特別是C++采用OOP技術(shù),提高程序開發(fā)的速度,同時編譯型語言較之解釋型語言更具有安全性。VisualBasic是MicrosoftWindow3.X/95/NT上的編程語言,VB用于CGI腳本的最大一特點是提供一個世界上最大的對象庫,并且提供OLE對象鏈接和嵌入技術(shù),所以VB是僅次于Perl的用于CGI腳本的語言。但VB最大的限制性是其設(shè)計的CGI腳本只可運行在基于Window系統(tǒng)的服務(wù)器平臺上。28/69返回新式編譯型腳本語言Java編程語言是由SunMicrosystem公司推行的,是現(xiàn)代國際互連網(wǎng)上的新生兒,Java的目標(biāo)是改變用于HTML和Web服務(wù)器的交互性,另外Java程序?qū)嶋H上運行在客戶端的瀏覽器中(IE/Netscape),通過由客戶機和服務(wù)器共同分擔(dān)數(shù)據(jù)處理的工作量,使得用Java開發(fā)的CGI腳本程序給服務(wù)器帶來了負荷的解放。Java的另一個特點是不依賴于OS系統(tǒng)和硬件平臺,Java編程語言開發(fā)CGI的局限性主要在于并非網(wǎng)上所有的游覽器都支持JVM技術(shù)。JavaScript是Netscape公司推出的CGI腳本程序的補充,JavaScript小巧、跨不同平臺,它基本上基于Java,可以看成是Java伴侶腳本語言,但其局限性是能運作在客戶端的瀏覽器中。VBScript是VB在Web上應(yīng)用的進一步發(fā)展,OLE技術(shù)的支持是VBScript的優(yōu)點,這為CGI程序直接鏈接到客戶端上的Window應(yīng)用程序提供了方便,局限性只能在Window系統(tǒng)平臺上。VisualJava++是Microsoft公司于1996年推出的一個能夠幫助用戶創(chuàng)建客戶和服務(wù)器端的強大軟體開發(fā)語言工具,它可以用于Internet上編寫網(wǎng)上操作系統(tǒng)軟件。29/69CGI與PHP、ASP的比較(一)30/69程序接口CGIPHPASP操作系統(tǒng)均可均可win32Web服務(wù)器均可數(shù)種IIS、PWS執(zhí)行效率慢快快穩(wěn)定性最高佳中等系統(tǒng)安全最佳佳極差函數(shù)支持一般多少網(wǎng)頁結(jié)合一般佳佳編程語言多phpVB、JavaScriptCGI與PHP、ASP的比較(二)程序接口CGIPHPASP開發(fā)難度較高低低開發(fā)時間中等短短移植性最好好差使用站點最多多多31/69CGI的工作原理當(dāng)客戶端的用戶完成了一定輸入工作后,向服務(wù)器發(fā)出HTTP請求(稱為CGI請求①)。服務(wù)器守護進程接受到該請求后,就創(chuàng)建一個子進程(稱為CGI進程

②),該CGI子進程將CGI的有關(guān)數(shù)據(jù)設(shè)置成環(huán)境變量③

。CGI子進程在外部CGI程序與服務(wù)器間建立兩條數(shù)據(jù)通道:標(biāo)準(zhǔn)I/O④

,然后啟動URL指定的CGI程序

⑤,與該子進程保持同步,以檢測CGI程序的執(zhí)行狀態(tài)。子進程通過標(biāo)準(zhǔn)輸出流將處理結(jié)果傳遞給服務(wù)器守護進程⑥,守護進程再將處理結(jié)果作為應(yīng)答信息回送給客戶端。CGI程序通過環(huán)境變量、命令行參數(shù)、標(biāo)準(zhǔn)輸入輸出與WWW服務(wù)器進行通信。CGI兩種調(diào)用方式--都要用HTTP請求--HTTP協(xié)議工作過程一致為什么要設(shè)置環(huán)境變量:為了通信32/69CGI工作原理示意圖33/69瀏覽器服務(wù)器CGI程序⑤其他程序或DB發(fā)出請求①返回格式文檔生成HTML文件⑥執(zhí)行程序調(diào)用系統(tǒng)中的其他程序返回結(jié)果HTTPCGICGI進程

②環(huán)境變量③標(biāo)準(zhǔn)I/O④1.當(dāng)客戶端的用戶完成了一定輸入工作后,向服務(wù)器發(fā)出HTTP請求(稱為CGI請求①)。2.服務(wù)器守護進程接受到該請求后,就創(chuàng)建一個子進程(稱為CGI進程

②),該CGI子進程將CGI的有關(guān)數(shù)據(jù)設(shè)置成環(huán)境變量③

。3.CGI子進程在外部CGI程序與服務(wù)器間建立兩條數(shù)據(jù)通道:標(biāo)準(zhǔn)I/O④

,然后啟動URL指定的CGI程序

⑤,與該子進程保持同步,以檢測CGI程序的執(zhí)行狀態(tài)。4.子進程通過標(biāo)準(zhǔn)輸出流將處理結(jié)果傳遞給服務(wù)器守護進程⑥,守護進程再將處理結(jié)果作為應(yīng)答信息回送給客戶端。34/69CGI的方法CGI方法是指調(diào)用主機應(yīng)用程序(簡稱CGI程序)時,Web服務(wù)器向其傳遞數(shù)據(jù)的方法和途徑。主要采用的方法為GET和

POST無論是采用GET方法還是采用POST方法,CGI程序均通過標(biāo)準(zhǔn)輸出STDOUT返回結(jié)果信息。最簡單的CGI程序--例一,例二*程序中第一條標(biāo)準(zhǔn)輸出語句告訴服務(wù)器傳輸內(nèi)容的MIME類型,

TEXT類型是指文本類型,包括Plaintext(純文本文件)、HTML文件*在VS2005中寫最簡單的CGI應(yīng)用程序:文件-新建項目-VisualC++-win32控制臺應(yīng)用程序;編譯;將生成的exe文件拷貝到wwwroot下相關(guān)的目錄下35/69例1的cgi程序名為E:\SHU\JXiedir\教學(xué)\web開發(fā)技術(shù)\PPT\Chap4\CSource\consoletry\consoletry\consoletry,演示建立項目和編譯應(yīng)該對Wwwroot目錄具有完全控制權(quán)限:1.打開我的電腦選擇工具-文件夾選項-查看-在高級設(shè)置下找到使用簡單文件共享取消打鉤;2.再右鍵單擊你想要打開的文件夾-屬性-安全-看看組和用戶名稱下面有沒有你當(dāng)前登錄的用戶名如果沒有就點添加輸入你當(dāng)前登錄的用戶名點確定選中剛才添加的用戶名帶下面把完全控制打鉤再點確定(簡單的辦法是,添加所有用戶的完全控制權(quán)限)36/69GET方法:數(shù)據(jù)的傳送:將數(shù)據(jù)附加在URL信息上傳送給WEB服務(wù)器,中間用“?”隔開,如:/cgi-bin/hello.exe?data,例數(shù)據(jù)的存儲:服務(wù)器處理該請求時,將調(diào)用由URL所指明的CGI程序而將“?”之后的數(shù)據(jù)信息存入環(huán)境變量QUERY_STRING之中。數(shù)據(jù)的獲?。篊GI程序需從QUERY_STRING環(huán)境變量中以字符串的形式獲取所需的數(shù)據(jù)。當(dāng)傳輸?shù)臄?shù)據(jù)不太長(小于1024個字符)時,可采用GET方法。POST方法數(shù)據(jù)的傳送:Web服務(wù)器通過標(biāo)準(zhǔn)輸入(STDIN)將Form的輸入信息進行包裝,向CGI程序傳輸數(shù)據(jù),而不是附加在Action所設(shè)定的URL之后。數(shù)據(jù)的讀?。篊GI程序從標(biāo)準(zhǔn)輸入(STDIN)實際讀取數(shù)據(jù)數(shù)據(jù)的長度在環(huán)境變量Content-Length中指明(Web服務(wù)器通過STDIN向CGI程序傳輸數(shù)據(jù)時,往往不在最后使用EOF結(jié)束標(biāo)記)。當(dāng)發(fā)送的數(shù)據(jù)要改變服務(wù)器上的數(shù)據(jù)或者想給CGI程序傳遞的數(shù)據(jù)很大(超過1024字節(jié))時,用這種方法。37/69Web服務(wù)器通過STDIN向CGI程序傳輸數(shù)據(jù)時,往往不在最后使用EOF結(jié)束標(biāo)記,因此,為了正確地讀取STDIN,CGI應(yīng)該使用CONTENT_LENGTH的值。38/69CGI實現(xiàn)交互式操作的方式基于文件(很少使用)使用FORMCGI傳送的數(shù)據(jù)從哪里來?39/69基于文件基于文件的操作是由運行CGI程序而產(chǎn)生HTML的文件,在這種文件的語句中嵌入<ISINDEX>標(biāo)識,其使用方法如下:

<ISINDEXACTION=“URL”>其中URL為需要執(zhí)行的CGI程序所在的路徑。在HTML文檔中使用該語句將產(chǎn)生一個輸入的窗口,讓用戶輸入。用戶輸入的值作為查詢字符串發(fā)給服務(wù)器,再次激活CGI程序,得到查詢結(jié)果。

ISINDEX常常用在廣域信息服務(wù)系統(tǒng)(WAIS)或用作檔案的搜索。但在CGI應(yīng)用中很少使用這種形式。40/69表單(FORM)HTML中的Form表單主要是為用戶在屏幕上建立一張表格,表格中有明確的文字提示,使用戶可以在表格上輸入自己的信息,然后使用提交按紐,將用戶的查詢條件傳送給服務(wù)器。表單是HTML文檔的一部分,用于搜集用戶信息表單沒有處理數(shù)據(jù)的能力輸入的信息將提交給Web服務(wù)器Web服務(wù)器上的CGI程序處理數(shù)據(jù)(存入數(shù)據(jù)文件/返回特定的信息)Form中的HTML代碼要完成兩件事:一是要指出CGI的路徑和名稱;二是將用戶輸入的信息傳遞給CGI。<FORM>標(biāo)記的屬性中最常用的是“ACTION”和“METHOD”。

“ACTION”指出要調(diào)用的CGI程序的URL地址?!癕ETHOD”主要有“GET”(缺省值)和“POST”兩種方法。41/69FORM表單的基本格式<FORMACTION="URL"METHOD="GET|POST">

表單元素(1)表單元素(2)表單元素(3)

......

</FORM>

42/69表單處理程序(即CGI程序)的URL地址。說明請求的CGI方法缺省設(shè)置,此時客戶數(shù)據(jù)用問號附加于指定URL之后FORM表單的表單元素表單元素多數(shù)由<INPUT>標(biāo)簽引入。根據(jù)其屬性“TYPE”的不同取值,可以引入不同的表單元素:

元素名

元素類型(TYPE)

單行文本輸入框

TEXT(TEXTFIELD)或PASSWORD

復(fù)選框

CHECKBOX

單選框

RADIO

提交按鈕

SUBMIT

重置按鈕

RESET

文件上傳

FILE<SELECT>標(biāo)簽引入選擇列表<TEXTAREA>標(biāo)簽引入多行文本輸入框43/69單行文本輸入框基本格式:

<INPUT

TYPE=TEXT或PASSWORD

NAME="text_id"

[MAXLENGTH=n1]

[SIZE=n2]

[VALUE="defaulttext"]>由input引入,type為text或password

44/69是傳遞給CGI程序的“名值對"數(shù)據(jù)的"名"部分限定最多可輸入的字符數(shù)指定文本框的長度(字符數(shù)),當(dāng)MAXLENGTH值大于SIZE值時,文字會自動向左滾動指定文本框的缺省值例復(fù)選框<INPUTTYPE=CHECKBOX

NAME="checkbox_id"

VALUE="choice_id"

[CHECKED]>

*可以有多個框被選中,提交時產(chǎn)生多個“名-值”對。

例45/69選擇項的名稱該框預(yù)先被選中單選框

<INPUTTYPE=RADIO

NAME="group_id"

VALUE="choice_id"

[CHECKED]>

同一組內(nèi)只能有一個單選按鈕被選中

例46/69同一組內(nèi)單選框的NAME屬性值必須相同指定單選框的值表示預(yù)先被選中重置按鈕基本格式:

<INPUTTYPE=RESET

[VALUE="Reset"]>

*重置按鈕用于重置(清除)表單中的內(nèi)容。*按鈕的標(biāo)簽可由VALUE指明。缺省為Reset(中文IE為“重置”).47/69提交按鈕基本格式:

<INPUTTYPE=SUBMIT

[VALUE="Submit"]>

*提交按鈕用于提交表單中的內(nèi)容。*按鈕的標(biāo)簽可由VALUE指明。缺省標(biāo)簽為SubmitQuery(中文IE為“提交查詢內(nèi)容”)

例48/69隱含域基本格式:

<INPUTTYPE=HIDDENNAME="hidden_id"VALUE="data_id">

*采用隱含域,可將信息嵌入到表單中而用戶卻看不到*提交表單時,隱含域中的信息同樣被送至CGI程序。*為什么需要隱含域?

當(dāng)前的HTTP協(xié)議(HTTP1.0)是無狀態(tài)的,這增加了CGI程序維護狀態(tài)信息的負擔(dān)。在多表單的應(yīng)用場合,為了將一個表單的狀態(tài)保留給另一個表單,可以采用隱含域方法。例:簡單表單;例:含有隱含域的表單49/69這是一種特殊的表單元素即它不能記住前面的請求所獲得的數(shù)據(jù),記住這些數(shù)據(jù)是CGI程序的事從地址欄可以看出,表單隱含域中保存的數(shù)據(jù)也提交給CGI程序了圖像按鈕基本格式:

<INPUT

TYPE=IMAGE

NAME="image_id"

SRC="image_url"

[ALIGN=TOP|MIDDLE|BOTTOM]>

*當(dāng)用戶單擊圖象時,其作用如同提交按鈕,將表單數(shù)據(jù)發(fā)送給表單處理程序。

*當(dāng)用戶單擊圖象時,該點的坐標(biāo)(a,b)將以“名值對”:image_id.x=a和image_id.y=b的形式與其它數(shù)據(jù)一同發(fā)送。

50/69FILE元素基本格式:<inputtype="file"

value="初始文件名"

name="field_id"

size=可視區(qū)域長度

maxlength=容許的最大字符長度

accept=可選擇的文件MIME類型列表,以逗號分隔>ACCEPT屬性限制了在文件對話框中出現(xiàn)的文件的類型,如:ACCEPT=“image/*”就限制文件類型為圖象文件,可用于上傳圖象文件。ENCTYPE=“multipart/form-data”用于表單里有圖片上傳:表單中enctype="multipart/form-data"的意思,是設(shè)置表單的MIME編碼。默認(rèn)情況,這個編碼格式是application/x-www-form-urlencoded,不能用于文件上傳;只有使用了multipart/form-data,才能完整的傳遞文件數(shù)據(jù),進行下面的操作.

enctype="multipart/form-data"是上傳二進制數(shù)據(jù)

51/69input標(biāo)簽的file元素讓用戶輸入一個文件名或通過“Browse”按鈕選取一個磁盤文件進行上載。選擇列表選擇列表在一個列表框中列出多個選項,基本格式:<SELECTNAME="list_id"[SIZE=n]

[MULTIPLE]>

<OPTION[VALUE="item_1"][SELECTED]>1stitem

<OPTION[VALUE="item_2"][SELECTED]>2nditem

<OPTION[VALUE="item_3"][SELECTED]>3rditem</SELECT>52/69指明可見選項的個數(shù),如果:省略SIZE屬性(即SIZE=1),列表就成了下拉列表;SIZE大于等于2,列表就成了顯示可見項數(shù)的滾動窗口;SIZE大于等于項數(shù)時,列表就成了無滾動條的固定窗口。表示可以選擇多項即多選列表指定選項的值,如果有多項被選中,提交時VALUE值將連成逗號分開的一串。如果省略VALUE屬性,提交時就用選項的內(nèi)容替代VALUE值。該項預(yù)先被選中例除了用input引入表單元素,也有個別元素不用input標(biāo)簽引入。其中一個就是選擇列表,它用select標(biāo)簽引入<SELECT>表示一個選擇框,類似單選按鈕和復(fù)選框,在一個列表框中列出多個選項例子中的food可以用shift選多項多行文本輸入域<TEXTAREA>表示一個多行文本輸入框,其結(jié)構(gòu)是

<TEXTAREANAME="field_id"[ROWS=n1]

[COLS=n2]

[WRAP]>

defaulttext

</TEXTAREA>除了用input引入表單元素,也有個別元素不用input標(biāo)簽引入53/69指定文本輸入域的行數(shù)。指定文本輸入域的列數(shù)。當(dāng)用戶的輸入到達文本輸入域的右邊界時自動換到下一行。例數(shù)據(jù)的組織和編碼(URL編碼)編碼規(guī)則:1)用“NAME=VALUE”形式組織客戶端提交的數(shù)據(jù)。2)每個“NAME=VALUE”對用&符號分開,按表單元素的先后次序排列,如:Name1=Value1&Name2=Value2&Name3=Value3&etc3)對客戶端輸入的數(shù)據(jù),除了英文字母、“@”符和阿拉伯?dāng)?shù)字外,其它輸入符號包括漢字和中文圖形符號,一律進行編碼。西文字符用2位十六進制的ASCII碼表示,中文字符用4位十六進制的漢字機內(nèi)碼表示,某些與保留字符相同的字符也將進行編碼用“%”標(biāo)記編碼的開始,且每2位十六進制數(shù)一隔。被譯碼后的字符被表示成一個“%”和它們的十六進制數(shù)形式(即%HH)??崭裼谩?”表示例:search:30%=x在用戶數(shù)據(jù)發(fā)往Web服務(wù)器之前,瀏覽器將對數(shù)據(jù)信息進行專門的處理,其中可能導(dǎo)致CGI程序出錯的字符將被替換,并且將數(shù)據(jù)組織得便于獲取。54/69NAME是表單元素的屬性,是Form中表單元素的名字,由“Name”屬性指定VALUE是表單元素的屬性,存儲客戶在表單中輸入的數(shù)據(jù)。如果客戶沒有輸入數(shù)據(jù),則VALUE存儲表單定義的缺省值,如果沒有缺省值,則為空值數(shù)據(jù)的組織和編碼(URL編碼)解碼規(guī)則:解碼的目的是將數(shù)據(jù)還原成客戶端用戶在Web頁面上輸入時的形式。URL解碼過程與編碼過程正好相反,它一般包括以下步驟:1)從瀏覽器用GET方法或POST方法傳送來的數(shù)據(jù)中分離出“NAME=VALUE”對。2)如果VALUE屬性中含有“+”號,則將其轉(zhuǎn)換成空格3)將VALUE中存放的十六進制數(shù)(“%HH”)轉(zhuǎn)換成相應(yīng)的ASCII字符。CGI程序從環(huán)境變量“QUERY_STRING”或標(biāo)準(zhǔn)輸入中讀入的數(shù)據(jù)是經(jīng)過瀏覽器URL譯碼過的,故在使用這些數(shù)據(jù)以前還必須對它們進行URL解碼。55/69CGI的環(huán)境變量環(huán)境變量是由Web服務(wù)器執(zhí)行CGI程序時所設(shè)置的與系統(tǒng)有關(guān)的變量服務(wù)器與CGI程序交換信息的協(xié)作方式是通過環(huán)境變量實現(xiàn)的。無論什么請求,CGI程序總能在特定位置找到某些信息。無論環(huán)境變量怎樣定義,總有一些變量有著特定含義。環(huán)境變量是一個保存用戶信息的內(nèi)存區(qū)。在CGI程序前,服務(wù)器在特定的環(huán)境變量中放入信息,CGI程序可以從這些環(huán)境中讀取所需的信息,并對其進行分析處理,從而實現(xiàn)客戶端網(wǎng)頁與服務(wù)數(shù)據(jù)交接。56/69與服務(wù)器相關(guān)的環(huán)境變量

GATEWAY_INTERFACE服務(wù)器遵守的CGI版本SERVER_NAME服務(wù)器的IP地址或域名SERVER_PORT主機的端口號SERVER_SOFTWARE服務(wù)器軟件的名字和版本SERVER_PROTOCOL服務(wù)器用于處理請求的協(xié)議名及版本號例:取與服務(wù)器有關(guān)的環(huán)境變量57/69與客戶機相關(guān)的環(huán)境變量HTTP_ACCEPT列出能被客戶機接受的內(nèi)容類型(MIME)列表如:image/gif,image/jpeg,text/html,text/plain等HTTP_USER_AGENT客戶機瀏覽器軟件的版本和名字如:Mozilla/4.0(compatible,MSIE4.0,Windows95)HTTP_REFERER訪問CGI時,客戶機所指向的HTML文檔的URL如:/cgi11.html例:取與客戶機有關(guān)的環(huán)境變量58/69與請求相關(guān)的環(huán)境變量CONTENT_LENGTHPOST方法中向標(biāo)準(zhǔn)輸入(STDIN)發(fā)送的字節(jié)數(shù)COTNENT_TYPEPOST方法中客戶機所發(fā)送數(shù)據(jù)的內(nèi)容類型(MIME類型)QUERY_STRINGGET方法中傳送給CGI程序的URL的問號(?)之后的那一部分REQUEST_METHOD

產(chǎn)生信息請求的CGI方法(GET/POST)例:取與請求有關(guān)的環(huán)境變量(GET方法,POST方法)注意:有的僅在post方法中使用,有的僅在get方法中使用59/69

CGI程序的基本結(jié)構(gòu)初始化處理輸出終止60/69初始化讀取REQUEST_METHOD環(huán)境變量,分析其中的內(nèi)容是GET還是POST。61/69#include<stdio.h>#include<stdlib.h>#include<string.h>main(){

char*pRequestMethod;

pRequestMethod=getenv("REQUEST_METHOD");

if

(pRequestMethod==NULL)

{

/*doerrorprocessing*/

}else

if

(strcmp(pRequestMethod,"GET")==0)

{

/*doGETprocessing*/

}else

if

(strcmp(pRequestMethod,"POST")==0)

{

/*doPOSTprocessing*/

}else

{

/*doerrorprocessing*/

}

}如果是GET方法,則讀取,分析并解碼QUERY_STRING

環(huán)境變量。CONTENT_TYPE的內(nèi)容類型為application/x-www-form-urlencoded,則分析并解碼從STDIN中讀取的數(shù)據(jù),數(shù)據(jù)長度在環(huán)境變量CONTENT_LENGTH中指明。如果CONTENT_TYPE

的值為NULL,表明數(shù)據(jù)是沒有經(jīng)過編碼處理。幾個自定義的常用函數(shù)voidreadGetData(char**aString)

讀取QUERY_STRING數(shù)據(jù)到數(shù)組

62/69#include<stdio.h>#include<stdlib.h>#defineMAX_LENGTH1000

charInputBuffer[MAX_LENGTH];voidreadGetData(char**aString){

char*pQueryString;

inti=0;

pQueryString=getenv("QUERY_STRING");

if

(pQueryString!=NULL)

for

(;*pQueryString!='\0';pQueryString++)

InputBuffer[i++]=*pQueryString;/*保存讀入的字符*/

InputBuffer[i]='\0';/*放入結(jié)束標(biāo)記*/

*aString=InputBuffer;}從QUERY_STRING

中讀入數(shù)據(jù)(不解碼)讀入的數(shù)據(jù)將存放在由*aString指向的InputBuffer[]

數(shù)組中幾個自定義的常用函數(shù)voidreadPostData(char**aString)從STDIN中讀入數(shù)據(jù)編碼規(guī)則63/69voidreadPostData(char**aString){char*pContentLength;

intContentLength;

inti=0;

pContentLength=getenv("CONTENT_LENGTH");

if

(pContentLength!=NULL)

ContentLength=atoi(pContentLength);/*輸入的字符數(shù)*/

else

ContentLength=0;

if

(ContentLength>MAX_LENGTH-1)

ContentLength=MAX_LENGTH-1;/*可容納的字符數(shù)*/for(i=0;i<ContentLength;i++){InputBuffer[i]=getchar();/*保存讀入的字符*/if((InputBuffer[i-1]=='=')&&(InputBuffer[i]=='&')){InputBuffer[i]=‘+’;//插入空格,解決輸入域為空時引起的錯誤InputBuffer[++i]='&';}}

InputBuffer[i]='\0';/*放入結(jié)束標(biāo)記*/

*aString=InputBuffer;}讀入的數(shù)據(jù)將存放在*aString指向的InputBuffer[]

數(shù)組中#defineMAX_LENGTH10000charInputBuffer[MAX_LENGTH]幾個自定義的常用函數(shù)intparseData(structentry

**queryString)分出輸入串中“名=值”對64/69intparseData(structentry**queryString){

char*pToken;

inti=0;

char*data=(char*)0;

readPostData(&data);/*若GET方法,可調(diào)用readGetData()*/

pToken=strtok(data,"=");/*查找第一個"="前的"名"*/

while

(pToken!=NULL){

entries[i].name=pToken;

pToken=strtok(NULL,"&");/*查找下一個"&"前的"值"*/

if

(pToken!=NULL)

{

entries[i++].val=pToken;

pToken=strtok(NULL,"=");/*查找下一個"="前的"名"*/

}

else{/*找不到下一個"&"前的"值"*/

pToken=strtok(NULL,'\0');/*查找結(jié)束標(biāo)記'\0'前的最后一個"值"*/

entries[i++].val=pToken;

break;

}

}

*queryString=entries;

return(i);

/*返回"名=值"對的個數(shù)*/}輸入串可調(diào)用readGetData()或readPostData()得到"名=值"對存放在一結(jié)構(gòu)體數(shù)組entries[]解碼后的數(shù)據(jù)仍存放在原結(jié)構(gòu)體數(shù)組中注意是i++,不是++i!幾個自定義的常用函數(shù)intDecodeData(structentry**pDecode)解碼URL編碼(由parseData()獲得)解碼和編碼是相反的過程,比如將字符“+”換成空格,將16進制轉(zhuǎn)換成10進制65/69intDecodeData(structentry**pDecode)

{

voidURLDecode(char*pEncoded);

inti,length;

structentry*data,*p;

length=parseData(&data);

p=data;

for(i=0;i<length;i++)

{

URLDecode(p->name);/*解碼"名"數(shù)據(jù)*/

URLDecode(p->val);/*解碼"值"數(shù)據(jù)*/

p++;

}

*pDecode=data;

return(length);

}voidURLDecode(char*pEncoded)

{char*p;

p=pEncoded;

for(;*pEncoded!='\0';pEncoded++,p++)

{if(*pEncoded=='+')

*p='';

/*將字符'+'換成空格*/

else{

if(*pEncoded=='%'){

pEncoded++;

if(isxdigit(*pEncoded)&&isxdigit(*(pEncoded+1)))

{

*p=(char)intFromHex(pEncoded);

pEncoded+=1;

}

else

*p=*pEncoded;

}

else

*p=*pEncoded;

}

}

*p='\0';}一個完整的例子66/69返回以POST方法為例:處理處理部分是CGI程序的核心,所要做的事完全依賴于CGI程序的應(yīng)用目標(biāo)。如:將用戶數(shù)據(jù)存入某數(shù)據(jù)庫文件根據(jù)用戶輸入查詢某數(shù)據(jù)庫文件根據(jù)用戶請求進行某種運算等67/69返回輸出(1)頭標(biāo)信息

頭標(biāo)信息用于讓服務(wù)器和客戶知道回送的信息類型,它可以是下面三種類型之一:內(nèi)容類型、位置、狀態(tài)。(2)標(biāo)準(zhǔn)輸出(STDOUT)

CGI程序通過標(biāo)準(zhǔn)輸出(STDOUT)將信息發(fā)送給等待的服務(wù)器,并由服務(wù)器回送給客戶。在C程序中,只需將回送內(nèi)容通過標(biāo)準(zhǔn)輸出語句輸出即可.

如:printf("Hello");對用戶數(shù)據(jù)進行讀取、解釋、處理后,需要向用戶返回輸出,這時需要給出頭標(biāo)信息和輸出內(nèi)容。

注意68/69返回頭標(biāo)信息:內(nèi)容類型頭標(biāo)(Content-type)指明回送內(nèi)容的MIME類型,主要有下面幾種:

application

應(yīng)用程序數(shù)據(jù),如壓縮文件。

audio

音頻數(shù)據(jù)

image

圖象數(shù)據(jù)

text

文本信息,

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論