大雀软件园

首页 软件下载 安卓市场 苹果市场 电脑游戏 安卓游戏 文章资讯 驱动下载
技术开发 网页设计 图形图象 数据库 网络媒体 网络安全 站长CLUB 操作系统 媒体动画 安卓相关
当前位置: 首页 -> 技术开发 -> 其他相关 -> 用VB编写标准CGI程序

用VB编写标准CGI程序

时间: 2021-07-31 作者:daque

运用通用网关接口(cgi),web效劳器不妨实行少许外部步调,并将那些外部程 序所爆发的输入截止和web效劳器所处置的静态文本、图像和声响融洽在一道传给相 应的web欣赏器。当存户机的欣赏器向web效劳器乞求一个html文献时,效劳器在收 到乞求后就去探求这个文献并将找到的文献传递给存户机。而当存户机的乞求是一 个cgi步调时,web效劳器将激活存户机所乞求的cgi步调并把步调的实行截止传给客 户机。    规范的cgi步调是经过情况变量和规范输出输入来与web效劳器调换消息的。任 何一个被体例激活的过程都具有规范输出和输入这两个文献句柄,cgi步调的过程 也不不同。然而,当cgi步调被web效劳器激活此后,它的规范输出stdin被贯穿到 web效劳器的规范输入stdout上,而cgi步调的规范输入stdout则被连到效劳器的标 准输出stdin上。所以,cgi步调从规范输出读守信息(也即是从web效劳器的规范 输入读消息),而它向规范输入写消息(也即是向web效劳器的规范输出写消息)。    web效劳器普遍将存户机传递来的消息放在它的规范输入和关系情况变量中而cgi步调则从情况变量和它的规范输出(也即是web效劳器的规范输入)获得所 需的消息,步调的最后输入截止则被写向它的规范输入stdout(也即是web效劳器的规范输出)。web效劳器将从它的规范输出stdin(也即是cgi步调的规范输 出)获得cgi步调的输入截止并将它传递给存户机。明显,web效劳器就像是存户机和cgi步调间的中介人。    web效劳器、cgi步调间的这种规范框架在unix体例下和微软windows情况中的字符办法下不妨处事得特殊好,由于此时体例爆发的一切过程都不妨存取规范输出和规范输入。但对于微软windows图形办法下的步调就不行了,由于它们没辙存取规范输出和规范输入。为领会决这一题目,微软在win32体例中创造了另一典型的规范输出和规范输入,步调不妨经过挪用win32 api因变量来存取规范输出和规范输入,然而,这就表示着运用这类规范输出和规范输入的cgi步调都必需是32位的。    微软windows情况下的其它少许web效劳器(比方website)则运用其余一种特出的本领(即运用ini文献)来实行web效劳器和cgi步调间的数据交谈。沿用这种被称为“win-cgi”典型编写的cgi步调常常只能在局部web效劳器上运转。普遍地,扶助win-cgi的web效劳器将存户端的输出以及相关的状况消息写入到一个ini文献中,而cgi步调则从该ini文献中获得关系消息,这类步调的实行功效没有规范cgi  步调高。    在举行cgi编制程序时,只有使cgi步调从规范输出和情况变量中获得存户机供给的消息,并将要传递给存户机的输入截止写入规范输入,剩下的消息传播处事将由web效劳器机动实行。cgi不过规则了一个规范的接口典型,只有按照这个规范典型,步调开拓职员就不妨运用百般编制程序东西(如perl、c、fortran、visual basic等)举行cgi编制程序了。商量到visualbasic的宏大的数据库处置本领、存户机/效劳器模  式的编制程序本领以及字符串处置本领,以是正文重要向大师引见怎样运用vb编写规范的cgi步调。    一、输出输入的处置    一个cgi步调被激活此后,它开始要做的工作即是决定体例平台、web效劳器和存户端欣赏器的状况消息以及存户端用户的输出数据。其余,它还必需不妨将关系消息传递给存户端,要不它将一事无成。那些操纵都是经过存取情况变量和规范输出输入来实行的。用vb编写的cgi步调经过挪用因变量environ( 来获得关系情况变量的值。存取规范输出输入就要在步调中运用win32api因变量getstdhandle( )、readfile( )和writefile( ),在运用那些因变量时开始必需在步调中证明它们,写证明语句时不妨借助于vb供给的api文本察看器。    以次的cgi步调说领会在vb-cgi步调中怎样处置情况变量和规范输出输入。该cgi步调特殊大略,可将规范输出中的消息不经任何处置就归来给存户端,它可被任何表单用post本领激活:    declare function getstdhandle lib "kernel32" (byval nstdhandle as long) as long     declare function readfile lib "kernel32" (byval hfile as long, lpbuffer as any,    byval nnumberofbytestoread as long, lpnumberofbytesread as long,lpoverlapped as any) as long    declare function writefile lib "kernel32" (byval hfile as long, byval lpbuffer as string,byval nnumberofbytestowrite as long, lpnumberofbyteswritten as long,lpoverlapped as any) as long    public const std_input_handle = -10&    public const std_output_handle = -11&    public const file_begin = 0&    public hstdin as long ’ 规范输出文献句柄    public hstdout as long ’ 规范输入文献句柄        sub main()    dim cgi_contentlength as string,cgi_querystring as string    dim lcontentlength as long ’ 规范输出中的字符串的长度    dim sbuff as string ’ 用来保存规范输出中的字符串    dim lbytesread as long ’ 本质读入的字符个数    dim rc as long    dim sformdata as string    ’挪用体例因变量天生规范输出输入文献句柄    hstdin = getstdhandle(std_input_handle)    hstdout = getstdhandle(std_output_handle)    ’获得情况变量content_length的值,并将它变换为整型    cgi_contentlength = environ("content_length")    lcontentlength = val(cgi_contentlength)    sbuff = string(lcontentlength, chr$(0))    ’从规范输出中读数据    rc = readfile(hstdin, byval sbuff, lcontentlength, lbytesread, byval 0&)    sformdata = left$(sbuff, lbytesread)    output "content-type: text/html" & vbcrlf    output ""    output ""    output "表单传递数据的本领post "    output "本cgi 步调运用visual basic体例! "    output "post本领传递的数据: "    output "" & sbuff    output ""    end sub    sub output(s as string) ’ 设置一个向规范输入写消息的因变量    dim lbyteswritten as long    s = s & vbcrlf    writefile hstdout, s, len(s), lbyteswritten, byval 0&    end sub [page_break] 普遍地,用vb编写翻译天生的cgi步调不许精确处置华文消息。这重要表此刻cgi步调向stdout输入的华文在web页面上没辙精确表露,可经过在该中笔墨符串后随着输入少许空格来处置这个题目。当运用html操作符、对web页面举行排版时,欣赏器在表露该web页面时会吃掉过剩的空格而只保持一个。在这种情景下,那些空格对web页面包车型的士表面基础上没有什么感化。即使运用html操作符、对web页面举行排版,则因为空格不许被欣赏器吃掉,以是web页面包车型的士表面将会遭到较大的感化。然而,这时候可用html的表格、来包办对web页面举行排版。    提防:所有cgi步调的主体必需放在main()因变量中。    二、url译码与解码    因为web效劳器和欣赏器不许精确处置少许特出的字符,web效劳器和欣赏器之间大概会所以而爆发那种水平的误解,以是在数据被传递之前,欣赏器都要对表单内存户输出的数据中的特出字符举行url译码。    比方,web体例用“=”领会表单各元素的name和value属性,用“&”领会各别表单位素的输出数据。即使在表单的输出数据中包括那些特出的字符,而且表单的数据在传递给web效劳器前不作任何处置,则web效劳器将没辙领会哪一个“=”、“&”是用户输出的,哪一个是欣赏器加上的。在由表单属性action设置的url中,也大概会展示少许特出的字符,当在cgi步调的称呼和路途消息(path information)中展示“=”、“&”和“?”时,城市感化数据的精确传递。    url译码(url encoding)即是将web效劳器所不许精确处置的特出字符变换成它的十六进制数的情势,比方将“%”变换成“%25”、“=”变换成“%3d”之类。那些特出的字符常常被称作web体例的保持字符。在web体例上不管是用get本领仍旧用post本领传递的数据都要举行url译码。cgi步调要想处置表单传递来的数据,还必需对欣赏器url译码过的数据举行解码。  所以,领会url译码对于咱们举行cgi编制程序利害常要害的。url译码普遍囊括以次办法:    1、欣赏器将所传递的数据按照表单所包括的元素领会成“name=value”情势,name和value辨别是表单位素的属性。个中,value属性中保存存户机在表单中输出的数据:即使存户机没有输出数据,则value保存的是表单设置的缺省值;即使缺省值也没有设置,则value值为空。    2、代办表单中各元素的各个“name=value”对被欣赏器用“&”贯穿起来。    3、value属性中寄存的数据若含有空格,则被变换成“+”。    4、url和输出数据中所包括的web体例的保持字符必需被译码成其十六进制数情势。    5、被译码后的字符被表白成一个“%”和它们的十六进制数情势(即%hh)。    cgi步调从情况变量“query_string”或规范输出中读入的数据是过程欣赏器url译码过的,故在运用那些数据往日还必需对它们举行url解码。解码的手段是将数据恢复成存户端用户在web页面上输时髦的情势。正文仍旧引见了url译码进程,url解码进程与它凑巧差异,它普遍囊括以次办法:    1、从欣赏器用get或post本领所传递来的数据中找到代办各个表单位素所积聚数据的“name=value”对。    2、value属性中所寄存的数据若含有“+”,则被变换成空格。    3、将value属性中所寄存的数据的十六进制数“%hh”变换成相映的字符。    web体例将中国字当成特出的字符,对它也要举行url译码。对于一个特出的单字节字符(比方“/”),欣赏器常常将它译码成十六进制数的情势(比方%2f), “%”表白它反面跟的是两位十六进制数。当vb步调对其举行处置时挪用chr$因变量就不妨将其回复为原貌。而一个中国字则被欣赏器译码成四位十六进制数(比方%d5%c5)。即使cgi步调还像往日那么辨别挪用chr(d5)和chr(c5),则因为d5、c5都不是平常的单字节十六进制数码,故chr因变量归来空,中国字将没辙精确恢复。精确的做法该当是将相关中国字的四位十六进制数一道传给因变量chr(如chr(d5c5)),此时中国字本领被精确恢复。    所以,不妨让cgi步调对四位贯串的十六进制数一道举行译码,再不使中国字不妨被精确恢复。但在这种情景下,当存户端用户输出了两个贯串的web体例保持字符时,cgi步调又大概把它们当成中国字来处置。这时候不妨让cgi步调在须要对四位贯串的十六进制数举行译码时开始查看前方两位能否为web体例的保持字符,即使是则仍旧依照单字节的字符处置。然而即使存户端用户在表单内填写了很多中国字,则cgi步调的承担将会大大加剧。究竟上,在大普遍情景下,存户端用户很少会运用两个贯串的web体例的保持字符,以是不妨只让cgi步调对最简单展示的景象如“://”(当存户端用户在表单中输出某一url时会展示这种情景)举行查看,正文下节供给的因变量urldecode( )不妨实行对中国字和web体例保持字符的url解码。    三、cgi编制程序范例    本节将用vb编写一个处置网页存户留言簿的cgi步调。除去要挪用正文前方所引见的win32api因变量外,步调中还挪用了win32api因变量gettempfilename() 来赢得一个独一的偶尔文献名。步调中的因变量urldecode()用来对存户端的输出举行url译码。因变量getcgivalue()则用来领会字符串,按照表单位素的name属性获得其value值,并挪用urldecode()因变量对其举行url译码。    本步调诉求在留言簿文献guests.html中运用一个定位串“”,将文献的发端局部和简直的存户留言局部划分。cgi步调将在“”地方的场所插入存户新的留言。guests.html应具备如次所示的款式:    ……………………….        这种款式将保护结果的留言出此刻留言簿的最前方。即使要想使结果的留言出此刻留言簿的结果面,则只需将留言簿文献中的定位字符串“>”移到留言簿文献中存户留言局部和html文献结果局部之间的场所就行了。  所有步调的完备代码如次所示:    ’guestbook.bas    declare function getstdhandle lib "kernel32" (byval nstdhandle as long) as long    declare function readfile lib "kernel32" (byval hfile as long, lpbuffer as any,byval nnumberofbytestoread as long, lpnumberofbytesread as long, lpoverlapped as any) as long    declare function writefile lib "kernel32" (byval hfile as long,byval lpbuffer as string, byval nnumberofbytestowrite as long,lpnumberofbyteswritten as long, lpoverlapped as any) as long    declare function gettempfilename lib "kernel32" alias "gettempfilenamea"(byval lpszpath as string, byval lpprefixstring as string, byval wunique as long, byval lptempfilename as string) as long    public const std_input_handle = -10&    public const std_output_handle = -11&    public const file_begin = 0&    public hstdin as long ’ 规范输出文献句柄    public hstdout as long ’ 规范输入文献句柄    public sformdata as string ’ 用来保存没有过程url译码的用户输出数据    public lcontentlength as long    public cgi_requestmethod as string        sub main()    dim cgi_contentlength as string, cgi_querystring as string, sbuff as string, chinesetail as string    dim lbytesread as long, rc as long,i as long    dim semail as string, sname as string, surl as string, sfrom as string, tempstring as string    dim scomment as string, tempfilename as string, guestbook as string    ’cgi步调的初始化处事    hstdin = getstdhandle(std_input_handle)    hstdout = getstdhandle(std_output_handle)    cgi_requestmethod = environ("request_method")    cgi_querystring = environ("query_string")    cgi_contentlength = environ("content_length")    lcontentlength = val(cgi_contentlength)    sbuff = string(lcontentlength, chr$(0))    output "content-type: text/html" & vbcrlf ’ 输入mime典型    output ""    if cgi_requestmethod = "post" then     sbuff = string(lcontentlength, chr$(0))     rc = readfile(hstdin, byval sbuff, lcontentlength, lbytesread, byval 0&)     sformdata = left$(sbuff, lbytesread)    elseif cgi_requestmethod = "get" then     sformdata = cgi_querystring    else     output "unknow form method !"    end if    chinesetail = string(400, " ")     ’为了在页面上精确表露华文,天生一个空格串以获得存户端用户的输出    sname = getcgivalue("name")    semail = getcgivalue("email")    surl = getcgivalue("url")    sfrom = getcgivalue("from")    scomment = getcgivalue("url_comment")    ’对存户端用户的输出举行查看    if len(sname) = 0 then     output "特殊对不起!您还没有填写全名!" & chinesetail     exit sub    end if    if len(scomment) = 0 then     output "特殊对不起!您还没有提出倡导!" & chinesetail     exit sub    end if    ’获得独一的偶尔文献名和留言簿文献并翻开它们    tempfilename = tempfile("c:windowstemp", "gbk")    guestbook = "e:netscapeserverdocsguests.html"    open tempfilename for output as #1    open guestbook for input as #2    do ’本轮回体用来将留言簿中字符串""前方的实质写入偶尔文献    line input #2, tempstring    print #1, tempstring    loop while tempstring <> "" and not eof(2)    ’向偶尔文献中插入存户端用户的留言 [page_break] print #1, "--------------------------------------------------------------------------------" & vbcrlf    print #1, "" & vbcrlf    print #1, "留言功夫:" & date$ & " " & time$ & vbcrlf    print #1, "全名: " & sname & vbcrlf    if len(semail) <> 0 then     print #1, "e-mail: " & semail & "" & vbcrlf    end if    if len(surl) <> 0 then     print #1, "我的网页: " & surl & "" & vbcrlf    end if    if len(sfrom) <> 0 then     print #1, "我来自: " & sfrom & vbcrlf    end if    print #1, "我的倡导: " & vbcrlf    print #1, scomment & vbcrlf    print #1, "" & vbcrlf    do ’本轮回体用来将留言簿结余的货色写入留言簿     line input #2, tempstring     print #1, tempstring     loop while not eof(2)    close #1    close #2    kill guestbook ’简略旧的留言簿    name tempfilename as guestbook ’将偶尔文献改成新的留言簿    output "特殊感动您的留言!" & chinesetail    output "欢送您常常光临本网页!" & chinesetail    output ""    end sub        sub output(s as string) ’ 簿本步调用来向规范输入写消息    dim lbyteswritten as long    s = s & vbcrlf    writefile hstdout, s, len(s), lbyteswritten, byval 0&    end sub        public function getcgivalue(cginame as string) as string    ’ 簿本步调不妨获得表单上某一元素的数据    dim delim2 as long ’ position of "="    dim delim1 as long ’ position of "&"    dim n as integer    dim pointer1 as long,pointer2 as long,length as long,length1 as long    dim tmpstring1 as string,tmpstring2 as string    pointer1 = 1    pointer2 = 1    delim2 = instr(pointer2, sformdata, "=")    pointer2 = delim2 + 1    do     length = delim2 - pointer1     tmpstring1 = mid(sformdata, pointer1, length)     delim1 = instr(pointer1, sformdata, "&")     pointer1 = delim1 + 1     length1 = delim1 - pointer2     if delim1 = 0 then length1 = lcontentlength + 1 - pointer2     if tmpstring1 = cginame then     tmpstring2 = mid$(sformdata, pointer2, length1)     getcgivalue = urldecode(tmpstring2)     exit do     end if     if delim1 = 0 then     exit do     end if     delim2 = instr(pointer2, sformdata, "=")     pointer2 = delim2 + 1     loop    end function        public function urldecode(byval sencoded as string) as string    ’ 本因变量不妨对用户输出的数据举行url解码    dim pointer as long ’ sencoded position pointer    dim pos as long ’ position of instr target    dim temp as string    if sencoded = "" then exit function    pointer = 1    do ’本轮回体用来将"+"变换成空格     pos = instr(pointer, sencoded, "+")     if pos = 0 then exit do     mid$(sencoded, pos, 1) = " "     pointer = pos + 1     loop     pointer = 1     do    ’本轮回体用来将%xx变换成字符。对于两个贯串的%xx,即使第一个%xx 不是某些特指的web体例保持字符,将把它们变换成中国字     pos = instr(pointer, sencoded, "%")     if pos = 0 then exit do     temp = chr$("&h" & (mid$(sencoded, pos + 1, 2)))     if mid(sencoded, pos + 3, 1) = "%" and (temp <> ":") and (temp <> "/") _     and (temp <> "(") and (temp <> ")") and (temp <> ".") and (temp <> ",") _     and (temp <> ";") and (temp <> "%") then     mid$(sencoded, pos, 2) = chr$("&h" & (mid$(sencoded, pos + 1, 2)) _     & (mid$(sencoded, pos + 4, 2)))     sencoded = left$(sencoded, pos) & mid$(sencoded, pos + 6)     pointer = pos + 1     else     mid$(sencoded, pos, 1) = temp     sencoded = left$(sencoded, pos) & mid$(sencoded, pos + 3)     pointer = pos + 1     end if     loop     urldecode = sencoded     exit function    end function        public function tempfile(spath as string, sprefix as string) as string     ’本因变量不妨赢得一个独一的偶尔文献名     dim x as long,rc as long     tempfile = string(127, chr$(0))     rc = gettempfilename(spath, sprefix, byval 0&, tempfile)     x = instr(tempfile, chr$(0))     if x > 0 then tempfile = left$(tempfile, x - 1)    end function        固然暂时仍旧有很多不妨代替cgi且其本能较cgi要高的本领(比方asp、isapi、nsapi等),但运用它们时须要用到特意的常识和东西,而且运用那些本领所体例的步调只实用于一定的web效劳器或体例平台。商量到cgi编制程序具备易用易学性、跨效劳器平台个性等便宜,所以,cgi步调还将在www上占领一席之地。

热门阅览

最新排行

Copyright © 2019-2021 大雀软件园(www.daque.cn) All Rights Reserved.