国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

用VB編寫標(biāo)準(zhǔn)CGI程序(上)

2019-11-18 17:27:31
字體:
供稿:網(wǎng)友
利用通用網(wǎng)關(guān)接口(CGI) Web服務(wù)器可以執(zhí)行一些外部程序 并將這些外部程序所產(chǎn)生的輸出結(jié)果和Web服務(wù)器所管理的靜態(tài)文本 圖像和聲音融合在一起傳給相應(yīng)的Web瀏覽器。當(dāng)客戶機(jī)的瀏覽器向Web服務(wù)器請(qǐng)求一個(gè)HTML文件時(shí) 服務(wù)器在收到請(qǐng)求后就去尋找這個(gè)文件并將找到的文件傳送給客戶機(jī)。而當(dāng)客戶機(jī)的請(qǐng)求是一個(gè)CGI程序時(shí) Web服務(wù)器將激活客戶機(jī)所請(qǐng)求的CGI程序并把程序的執(zhí)行結(jié)果傳給客戶機(jī)。

  標(biāo)準(zhǔn)的CGI程序是通過環(huán)境變量和標(biāo)準(zhǔn)輸入輸出來與Web服務(wù)器交換信息的。任何一個(gè)被系統(tǒng)激活的進(jìn)程都擁有標(biāo)準(zhǔn)輸入和輸出這兩個(gè)文件句柄 CGI程序的進(jìn)程也不例外。不過 當(dāng)CGI程序被Web服務(wù)器激活以后 它的標(biāo)準(zhǔn)輸入STDIN被連接到Web服務(wù)器的標(biāo)準(zhǔn)輸出STDOUT上 而CGI程序的標(biāo)準(zhǔn)輸出STDOUT則被連到服務(wù)器的標(biāo)準(zhǔn)輸入STDIN上。因此 CGI程序從標(biāo)準(zhǔn)輸入讀取信息(也就是從Web服務(wù)器的標(biāo)準(zhǔn)輸出讀信息) 而它向標(biāo)準(zhǔn)輸出寫信息(也就是向Web服務(wù)器的標(biāo)準(zhǔn)輸入寫信息)。

  Web服務(wù)器一般將客戶機(jī)傳送來的信息放在它的標(biāo)準(zhǔn)輸出和相關(guān)環(huán)境變量中 而CGI程序則從環(huán)境變量和它的標(biāo)準(zhǔn)輸入(也就是Web服務(wù)器的標(biāo)準(zhǔn)輸出)獲取所需的信息 程序的最終輸出結(jié)果則被寫向它的標(biāo)準(zhǔn)輸出STDOUT(也就是Web服務(wù)器的標(biāo)準(zhǔn)輸入)。Web服務(wù)器將從它的標(biāo)準(zhǔn)輸入STDIN(也就是CGI程序的標(biāo)準(zhǔn)輸出)獲取CGI程序的輸出結(jié)果并將它傳送給客戶機(jī)。客戶機(jī) Web服務(wù)器和CGI程序之間的信息交流如下圖所示。顯然 Web服務(wù)器就像是客戶機(jī)和CGI程序間的中介。

  Web服務(wù)器 CGI程序間的這種標(biāo)準(zhǔn)框架在Unix系統(tǒng)下和微軟Windows環(huán)境中的字符方式下可以工作得非常好 因?yàn)榇藭r(shí)系統(tǒng)產(chǎn)生的所有進(jìn)程都可以存取標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出。但對(duì)于微軟Windows圖形方式下的程序就不行了 因?yàn)樗鼈儫o法存取標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出。為了解決這一問題 微軟在Win32系統(tǒng)中創(chuàng)建了另一類型的標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出 程序可以通過調(diào)用Win32API函數(shù)來存取標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出 不過 這就意味著使用這類標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出的CGI程序都必須是32位的。

  微軟Windows環(huán)境下的其它一些Web服務(wù)器(例如Website)則使用另外一種特殊的技術(shù)(即利用INI文件)來實(shí)現(xiàn)Web服務(wù)器和CGI程序間的數(shù)據(jù)交流。采用這種被稱為“Win-CGI”規(guī)范編寫的CGI程序通常只能在部份Web服務(wù)器上運(yùn)行。一般地 支持Win-CGI的Web服務(wù)器將客戶端的輸入以及有關(guān)的狀態(tài)信息寫入到一個(gè)INI文件中 而CGI程序則從該INI文件中獲取相關(guān)信息 這類程序的執(zhí)行效率沒有標(biāo)準(zhǔn)CGI程序高。

  在進(jìn)行CGI編程時(shí) 只要使CGI程序從標(biāo)準(zhǔn)輸入和環(huán)境變量中獲取客戶機(jī)提供的信息 并將要傳送給客戶機(jī)的輸出結(jié)果寫入標(biāo)準(zhǔn)輸出 剩下的信息傳遞工作將由Web服務(wù)器自動(dòng)完成。CGI只是規(guī)定了一個(gè)標(biāo)準(zhǔn)的接口規(guī)范 只要遵守這個(gè)標(biāo)準(zhǔn)規(guī)范 程序開發(fā)人員就可以利用各種編程工具(如Perl C FORTRAN VisualBasic等)進(jìn)行CGI編程了。考慮到VisualBasic的強(qiáng)大的數(shù)據(jù)庫處理能力 客戶機(jī)/服務(wù)器模式的編程能力以及字符串處理能力 所以本文主要向大家介紹如何使用VB編寫標(biāo)準(zhǔn)的CGI程序。

  一 輸入輸出的處理

  一個(gè)CGI程序被激活以后 它首先要做的事情就是確定系統(tǒng)平臺(tái) Web服務(wù)器和客戶端瀏覽器的狀態(tài)信息以及客戶端用戶的輸入數(shù)據(jù)。此外 它還必須能夠?qū)⑾嚓P(guān)信息傳送給客戶端 否則它將一事無成。這些操作都是通過存取環(huán)境變量和標(biāo)準(zhǔn)輸入輸出來完成的。用VB編寫的CGI程序通過調(diào)用函數(shù)Environ()來獲取相關(guān)環(huán)境變量的值。存取標(biāo)準(zhǔn)輸入輸出就要在程序中使用Win32API函數(shù)GetStdHandle() ReadFile()和WriteFile() 在使用這些函數(shù)時(shí)首先必須在程序中聲明它們 寫聲明語句時(shí)可以借助于VB提供的API文本查看器。

  以下的CGI程序說明 在VB-CGI程序中如何處理環(huán)境變量和標(biāo)準(zhǔn)輸入輸出。該CGI程序非常簡(jiǎn)單 可將標(biāo)準(zhǔn)輸入中的信息不經(jīng)任何處理就返回給客戶端 它可被任何表單用POST方法激活 

  DeclareFunctionGetStdHandleLib"kernel32"(ByValnStdHandleAsLong)AsLong

  DeclareFunctionReadFileLib"kernel32"(ByValhFileAsLong,lpBufferAsAny,

  ByValnNumberOfBytesToReadAsLong,lpNumberOfBytesReadAsLong,lpOverlappedAsAny)AsLong

  DeclareFunctionWriteFileLib"kernel32"(ByValhFileAsLong,ByVallpBufferAsString,ByValnNumberOfBytesToWriteAsLong,lpNumberOfBytesWrittenAsLong,lpOverlappedAsAny)AsLong

  PublicConstSTD_INPUT_HANDLE=-10&

  PublicConstSTD_OUTPUT_HANDLE=-11&

  PublicConstFILE_BEGIN=0&

  PublichStdInAsLong'標(biāo)準(zhǔn)輸入文件句柄

  PublichStdOutAsLong'標(biāo)準(zhǔn)輸出文件句柄



  SubMain()

  DimCGI_ContentLengthAsString CGI_QueryStringAsString

  DimlContentLengthAsLong'標(biāo)準(zhǔn)輸入中的字符串的長(zhǎng)度

  DimsBuffAsString'用于存儲(chǔ)標(biāo)準(zhǔn)輸入中的字符串

  DimlBytesReadAsLong'實(shí)際讀入的字符個(gè)數(shù)

  DimrcAsLong

  DimsFormDataAsString

  '調(diào)用系統(tǒng)函數(shù)生成標(biāo)準(zhǔn)輸入輸出文件句柄

  hStdIn=GetStdHandle(STD_INPUT_HANDLE)

  hStdOut=GetStdHandle(STD_OUTPUT_HANDLE)

  '獲取環(huán)境變量CONTENT_LENGTH的值 并將它轉(zhuǎn)換為整型

  CGI_ContentLength=Environ("CONTENT_LENGTH")

  lContentLength=Val(CGI_ContentLength)

  sBuff=String(lContentLength,Chr$(0))

  '從標(biāo)準(zhǔn)輸入中讀數(shù)據(jù)

  rc=ReadFile(hStdIn,ByValsBuff,lContentLength,lBytesRead,ByVal0&)

  sFormData=Left$(sBuff,lBytesRead)

  OutPut"Content-type:text/html"&vbCrLf

  OutPut"<HTML><HEAD>"

  OutPut"<TITLE>表單傳送數(shù)據(jù)的方法POST</TITLE></HEAD>"

  OutPut"<BODY><H3>表單傳送數(shù)據(jù)的方法POST</H3>"

  OutPut"<P>本CGI程序使用VisualBasic編制 "

  OutPut"<P>POST方法傳送的數(shù)據(jù):"

  OutPut"<P>"&sBuff

  OutPut"</BODY></HTML>"

  EndSub

  SubOutPut(sAsString)'定義一個(gè)向標(biāo)準(zhǔn)輸出寫信息的函數(shù)

  DimlBytesWrittenAsLong

  s=s&vbCrLf

  WriteFilehStdOut,s,Len(s),lBytesWritten,ByVal0&

  EndSub

  一般地 用VB編譯生成的CGI程序不能正確處理中文信息。這主要表現(xiàn)在CGI程序向STDOUT輸出的中文在Web頁面上無法正確顯示 可通過在該中文字符串后跟著輸出一些空格來解決這個(gè)問題。當(dāng)使用HTML標(biāo)識(shí)符<P> </P>對(duì)Web頁面進(jìn)行排版時(shí) 瀏覽器在顯示該Web頁面時(shí)會(huì)吃掉多馀的空格而只保留一個(gè)。在這種情況下 這些空格對(duì)Web頁面的外觀基本上沒有什堋影響。如果使用HTML標(biāo)識(shí)符<PRE> </PRE>對(duì)Web頁面進(jìn)行排版 則由于空格不能被瀏覽器吃掉 所以Web頁面的外觀將會(huì)受到較大的影響。不過 這時(shí)可用HTML的表格<table> <P>來代替<PRE>對(duì)Web頁面進(jìn)行排版。

  注意 整個(gè)CGI程序的主體必須放在MAIN()函數(shù)中。

  二 URL譯碼與解碼

  由于Web服務(wù)器和瀏覽器不能正確處理一些特殊的字符 Web服務(wù)器和瀏覽器之間可能會(huì)因此而產(chǎn)生某種程度的誤會(huì) 所以在數(shù)據(jù)被傳送之前 瀏覽器都要對(duì)表單內(nèi)客戶輸入的數(shù)據(jù)中的特殊字符進(jìn)行URL譯碼。

  例如 Web系統(tǒng)用“=”分解表單各元素的NAME和VALUE屬性 用“&”分解不同表單元素的輸入數(shù)據(jù)。如果在表單的輸入數(shù)據(jù)中包含這些特殊的字符 并且表單的數(shù)據(jù)在傳送給Web服務(wù)器前不作任何處理 則Web服務(wù)器將無法知道哪一個(gè)“=” “&”是用戶輸入的 哪一個(gè)是瀏覽器加上的。在由表單屬性ACTION定義的URL中 也可能會(huì)出現(xiàn)一些特殊的字符 當(dāng)在CGI程序的名稱和路徑信息(PathInformation)中出現(xiàn)“=” “&”和“ ”時(shí) 都會(huì)影響數(shù)據(jù)的正確傳送。

  URL譯碼(URLEncoding)就是將Web服務(wù)器所不能正確處理的特殊字符轉(zhuǎn)換成它的十六進(jìn)制數(shù)的形式 比如將“”轉(zhuǎn)換成“%” “=”轉(zhuǎn)換成“=”等等。這些特殊的字符通常被稱作Web系統(tǒng)的保留字符。在Web系統(tǒng)上無論是用GET方法還是用POST方法傳送的數(shù)據(jù)都要進(jìn)行URL譯碼。CGI程序要想處理表單傳送來的數(shù)據(jù) 還必須對(duì)瀏覽器URL譯碼過的數(shù)據(jù)進(jìn)行解碼。因此 理解URL譯碼對(duì)于我們進(jìn)行CGI編程是非常重要的。URL譯碼一般包括以下步驟 

  1 瀏覽器將所傳送的數(shù)據(jù)根據(jù)表單所包含的元素分解成“NAME=VALUE”形式 NAME和VALUE分別是表單元素的屬性。其中 VALUE屬性中存儲(chǔ)客戶機(jī)在表單中輸入的數(shù)據(jù) 如果客戶機(jī)沒有輸入數(shù)據(jù) 則VALUE存儲(chǔ)的是表單定義的缺省值如果缺省值也沒有定義 則VALUE值為空。

  2 代表表單中各元素的各個(gè)“NAME=VALUE”對(duì)被瀏覽器用“&”連接起來。

  3 VALUE屬性中存放的數(shù)據(jù)若含有空格 則被轉(zhuǎn)換成“ ”。

  4 URL和輸入數(shù)據(jù)中所包含的Web系統(tǒng)的保留字符必須被譯碼成其十六進(jìn)制數(shù)形式。

  5 被譯碼后的字符被表示成一個(gè)“”和它們的十六進(jìn)制數(shù)形式(即HH)。

  CGI程序從環(huán)境變量“QUERY_STRING”或標(biāo)準(zhǔn)輸入中讀入的數(shù)據(jù)是經(jīng)過瀏覽器URL譯碼過的 故在使用這些數(shù)據(jù)以前還必須對(duì)它們進(jìn)行URL解碼。解碼的目的是將數(shù)據(jù)還原成客戶端用戶在Web頁面上輸入時(shí)的形式。本文已經(jīng)介紹了URL譯碼過程 URL解碼過程與它正好相反 它一般包括以下步驟 

  1 從瀏覽器用GET或POST方法所傳送來的數(shù)據(jù)中找出代表各個(gè)表單元素所儲(chǔ)存數(shù)據(jù)的“NAME=VALUE”對(duì)。

  2 VALUE屬性中所存放的數(shù)據(jù)若含有“ ” 則被轉(zhuǎn)換成空格。

  3 將VALUE屬性中所存放的數(shù)據(jù)的十六進(jìn)制數(shù)“HH”轉(zhuǎn)換成相應(yīng)的字符。

  Web系統(tǒng)將漢字當(dāng)成特殊的字符 對(duì)它也要進(jìn)行URL譯碼。對(duì)于一個(gè)特殊的單字節(jié)字符(比如“/”) 瀏覽器通常將它譯碼成十六進(jìn)制數(shù)的形式(比如/) “”表示它后面跟的是兩位十六進(jìn)制數(shù)。當(dāng)VB程序?qū)ζ溥M(jìn)行處理時(shí)調(diào)用Chr$函數(shù)就可以將其恢復(fù)為原貌。而一個(gè)漢字則被瀏覽器譯碼成四位十六進(jìn)制數(shù)(比如張)。如果CGI程序還像以前那樣分別調(diào)用Chr(D5)和Chr(C5) 則由于D5 C5都不是正常的單字節(jié)十六進(jìn)制數(shù)碼 故Chr函數(shù)返回空 漢字將無法正確還原。正確的做法應(yīng)該是將有關(guān)漢字的四位十六進(jìn)制數(shù)一起傳給函數(shù)Chr(如Chr(D5C5)) 此時(shí)漢字才能被正確還原。

  因此 可以讓CGI程序?qū)λ奈贿B續(xù)的十六進(jìn)制數(shù)一起進(jìn)行譯碼 以便使?jié)h字能夠被正確還原。但在這種情況下 當(dāng)客戶端用戶輸入了兩個(gè)連續(xù)的Web系統(tǒng)保留字符時(shí) CGI程序又可能把它們當(dāng)成漢字來處理。這時(shí)可以讓CGI程序在 要對(duì)四位連續(xù)的十六進(jìn)制數(shù)進(jìn)行譯碼時(shí)首先檢查前面兩位是否為Web系統(tǒng)的保留字符 如果是則仍然按照單字節(jié)的字符處理。不過如果客戶端用戶在表單內(nèi)填寫了很多漢字 則CGI程序的負(fù)擔(dān)將會(huì)大大加重。事實(shí)上 在大多數(shù)情況下 客戶端用戶很少會(huì)使用兩個(gè)連續(xù)的Web系統(tǒng)的保留字符 所以可以只讓CGI程序?qū)ψ钊菀壮霈F(xiàn)的情形如“://”(當(dāng)客戶端用戶在表單中輸入某一URL時(shí)會(huì)出現(xiàn)這種情況)進(jìn)行檢查 本文下節(jié)提供的函數(shù)UrlDecode()可以實(shí)現(xiàn)對(duì)漢字和Web系統(tǒng)保留字符的URL解碼。->


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 华宁县| 育儿| 西乡县| 乐安县| 霍林郭勒市| 铁力市| 商水县| 山西省| 南乐县| 兰州市| 邳州市| 托克托县| 阿拉善右旗| 江孜县| 武城县| 夏津县| 西安市| 渝中区| 灵川县| 黄大仙区| 嘉黎县| 开原市| 新闻| 德安县| 且末县| 苏尼特左旗| 镇巴县| 乌拉特后旗| 安顺市| 三穗县| 南川市| 科技| 鱼台县| 成安县| 和田市| 呈贡县| 斗六市| 嘉义市| 神木县| 大渡口区| 连山|