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

首頁 > 開發(fā) > XML > 正文

實(shí)戰(zhàn)ASP(7):使用ASP、VB和XML建立運(yùn)行于互聯(lián)網(wǎng)上的應(yīng)用程序(上)

2024-09-05 20:55:41
字體:
供稿:網(wǎng)友
使用asp、vb和xml建立運(yùn)行于互聯(lián)網(wǎng)上的應(yīng)用程序(1)
     在個(gè)人電腦上使用單機(jī)版應(yīng)用軟件的時(shí)代很快就要過去了,現(xiàn)在大部分的應(yīng)用程序都開發(fā)出網(wǎng)絡(luò)版或大都需要共享網(wǎng)絡(luò)上豐富的數(shù)據(jù)資源。我們雖然寫了很長時(shí)間基于客戶端/服務(wù)器的應(yīng)用程序,但是這些程序大部分只是運(yùn)行在小型的局域網(wǎng)內(nèi)部。然而,有很多客觀的原因要求我們要修改這些程序以使它們能夠運(yùn)行在一個(gè)企業(yè)的內(nèi)部網(wǎng)甚至是國際互聯(lián)網(wǎng)。

  是什么原因迫使我們做呢?首先,隨著一個(gè)企業(yè)的規(guī)模逐漸擴(kuò)大,公司可能會(huì)跨地區(qū)甚至跨國經(jīng)營,每個(gè)分公司的員工的數(shù)量也會(huì)逐年增多,這些在外地的員工肯定需要頻繁地訪問總公司的數(shù)據(jù)庫資源;其次,集中應(yīng)用程序的數(shù)據(jù)資源,能夠使你更好的監(jiān)控?cái)?shù)據(jù)庫的訪問和使用情況。第三,你可以通過從一個(gè)集中的位置獲取全局應(yīng)用程序設(shè)置,從而維護(hù)和更新它們,最終達(dá)到緩減應(yīng)用程序更新的目的。第四,盡量從web服務(wù)器上訪問數(shù)據(jù)庫而不是從客戶端上訪問數(shù)據(jù)庫,這樣可以避免通過網(wǎng)絡(luò)傳送登錄信息和客戶密碼,從而避免安全隱患;而且,使用瀏覽器從后臺(tái)獲取數(shù)據(jù),這樣能夠避免刷新整個(gè)頁面。

  這就要求我們創(chuàng)建一個(gè)運(yùn)行于互聯(lián)網(wǎng)上的應(yīng)用程序,而假如想創(chuàng)建一個(gè)運(yùn)行在http協(xié)議上的vb程序,那么關(guān)鍵就是使用xml和xmlhttprequest對(duì)象。這個(gè)對(duì)象是microsoft xml分析器(msxml.dll)的一部分,xmlhttprequest對(duì)象可以讓你通過http向遠(yuǎn)程服務(wù)器發(fā)送get和post請(qǐng)求,運(yùn)行在遠(yuǎn)程服務(wù)器上的程序接收這個(gè)請(qǐng)求,翻譯出它的內(nèi)容,返回?cái)?shù)據(jù)或者一個(gè)錯(cuò)誤頁面到調(diào)用它的應(yīng)用程序。對(duì)網(wǎng)絡(luò)編程有一些研究的朋友會(huì)看出我這個(gè)設(shè)想很象soap,但是在這里我不想使用soap,因?yàn)槿绻菢拥脑挄?huì)使程序變得很復(fù)雜。

  想要改變一個(gè)完全獨(dú)立的客戶端單機(jī)版程序是不太現(xiàn)實(shí)的,但即使如此,從一個(gè)集中的服務(wù)器上下載應(yīng)用程序設(shè)置也比使用本地的ini文件或windows注冊(cè)標(biāo)有更大的獨(dú)立性和靈活性。舉例來說,假設(shè)你有一支手機(jī)銷售隊(duì)伍,他們需要訪問集中化的信息來更有效的銷售手機(jī),每天,總公司集中收集數(shù)據(jù),然后用電子郵件的形式發(fā)送給銷售人員。然而,市場(chǎng)的壓力和迅速變化的銷售形式勢(shì)必使銷售人員要訪問最新的數(shù)據(jù)信息。但是,網(wǎng)絡(luò)管理員卻堅(jiān)持拒絕讓在遠(yuǎn)程客戶端的銷售人員訪問總公司數(shù)據(jù)庫服務(wù)器,因?yàn)樗麄儾幌胪ㄟ^公用的網(wǎng)絡(luò)發(fā)送用戶名和登錄密碼。因此勢(shì)必要使用一種新的技術(shù)代替基于客戶端/服務(wù)器的技術(shù),不要著急,我想看完本文你就會(huì)解決這個(gè)問題的。

  讓我們先分析一下客戶端/服務(wù)器應(yīng)用程序。在一個(gè)標(biāo)準(zhǔn)的客戶端/服務(wù)器應(yīng)用程序中,在應(yīng)用程序開始時(shí),你能夠初始化數(shù)據(jù)庫連接字符串,這就意味著,客戶有使用數(shù)據(jù)庫連接字符串的權(quán)利,這包括用戶名和口令。但是客觀情況如果不允許你在網(wǎng)絡(luò)上發(fā)送這些信息的話,你就必需在不聯(lián)接數(shù)據(jù)庫的情況下直接從客戶端取得數(shù)據(jù)發(fā)送給客戶。那么解決方案之一就是在服務(wù)器上創(chuàng)建一個(gè)asp頁(在本例中稱為getdata.asp)接收特定格式的post數(shù)據(jù),它要求一個(gè)包含xml字符串,用來創(chuàng)建ado對(duì)象并運(yùn)行存儲(chǔ)過程或動(dòng)態(tài)sql語句命令。如果信息有效的話,getdata.asp執(zhí)行存儲(chǔ)過程,并返回一個(gè)xml格式的數(shù)據(jù)集、返回值列表或錯(cuò)誤頁面信息的xml字符串。對(duì)于返回?cái)?shù)據(jù)的命令,客戶端要么重新實(shí)例化要么返回值或使用xml dom(document object model文檔對(duì)象模型)格式的錯(cuò)誤頁面。

  好,下面就讓我們來討論一下如何實(shí)現(xiàn)這個(gè)頁面吧!

  getdata.asp頁面首先使用一個(gè)domdocument對(duì)象來保存客戶端發(fā)送的數(shù)據(jù):

  '創(chuàng)建domdocument對(duì)象
  set xml = server.createobject ("msxml2.domdocument")
  xml.async = false

  然后,它裝載post數(shù)據(jù)

  '裝載post數(shù)據(jù)
  xml.load request
  if xml.parseerror.errorcode <> 0 then
   call responseerror ("不能裝載xml信息。" & "description: " & xml.parseerror.reason & "<br>line: " & xml.parseerror.line)
  end if

  它能夠返回commandtext元素值和returndata或returnvalue元素值。下面我只給出返回commandtext元素值的代碼,其余代碼請(qǐng)參看我下面所附的源程序。

  set n = xml.selectsinglenode("command/commandtext")
  if n is nothing then
   call responseerror ("缺少 <sp_name> 參數(shù)。")
  else sp_name = n.text
  end if

  接著,應(yīng)該讓頁面創(chuàng)建一個(gè)command對(duì)象,讀入所有<param>元素,并且為request中的每一個(gè)元素創(chuàng)建一個(gè)參數(shù)。最后,讓頁面打開一個(gè)連接使用存儲(chǔ)過程adexecutenorecords選項(xiàng)來執(zhí)行request。

  set conn = server.createobject("adodb.connection")
  conn.mode=admodereadwrite
  conn.open application("connectionstring")
  set cm.activeconnection=conn
  ' 返回?cái)?shù)據(jù)
  if not returnsdata then
    cm.execute
  else
   set r = server.createobject("adodb.recordset")
   r.cursorlocation = aduseclient
   r.open cm, ,adopenstatic, adlockreadonly
  end if

  如果能夠返回?cái)?shù)據(jù)的話,那么returndata變量就為真值,并且把結(jié)果數(shù)據(jù)集返回到客戶端,仍然是一個(gè)xml文檔。

  if returnsdata then
   r.save response, adpersistxml
    if err.number <> 0 then
     call responseerror ("數(shù)據(jù)集發(fā)生存儲(chǔ)錯(cuò)誤" & "在命令'" & commandtext & "': " &    err.description)
     response.end
    end if

  如果輸出參數(shù)返回值,那么這個(gè)頁面將返回一個(gè)包含這些值的xml字符串。文檔的根元素是一個(gè)<values>標(biāo)記,每一個(gè)返回值都有其相應(yīng)的子元素,如果發(fā)生任何錯(cuò)誤,頁面都會(huì)格式化并返回一個(gè)包含錯(cuò)誤信息的xml字符串:

  sub responseerror(sdescription)
   response.write "<response><data>錯(cuò)誤: " & sdescription & "</data></response>"
   response.end
  end sub

  假設(shè)在我們前面所說的例子中,我們想在應(yīng)用程序中顯示區(qū)域的左半邊顯示客戶的姓名列表,再在每個(gè)客戶姓名后面加上兩個(gè)鏈接:purchase history和recent purchase。當(dāng)用戶點(diǎn)擊其中的一個(gè)鏈接,客戶程序就會(huì)運(yùn)行一個(gè)存儲(chǔ)過程并在右邊區(qū)域顯示出結(jié)果。 為了顯示這個(gè)想法的靈活性,我想讓用于返回?cái)?shù)據(jù)的三個(gè)操作單元執(zhí)行不同的工作過程,它們都調(diào)用getdata.asp。首先,通過調(diào)用custorderhist來運(yùn)行一個(gè)存儲(chǔ)過程,返回客戶的purchase history,它搜索northwind數(shù)據(jù)庫(為了方便起見我使用ms sql中自帶的數(shù)據(jù)庫)并返回一個(gè)數(shù)據(jù)集。用于返回recent purchase 的查詢語句運(yùn)行一個(gè)叫recentpurchasebycustomerid的存儲(chǔ)過程,來接收輸入的customerid參數(shù)并通過productname參數(shù)返回最近顧客購買的商品名。定義其處理過程相應(yīng)sql語句如下:

  create procedure recentpurchasebycustomerid @customerid nchar(5), @productname nchar(40) output as select @productname = (select top 1 productname from products inner join ([order details] inner join orders on orders.orderid=[order details].orderid) on products.productid = [order details].productid where orders.orderdate = (select max(orders.orderdate) from orders
where [email protected]) and [email protected]) go

  不管你的查詢語句中含有動(dòng)態(tài)sql語句還是含有返回記錄集的存儲(chǔ)過程或是輸出一個(gè)返回值,其處理post消息的方法是一樣的:

  set xhttp = createobject ("msxml2.xmlhttp")
  xhttp.open "post", "http://localhost/myweb/ getdata.asp", false
  xhttp.send s

  好了,現(xiàn)在讓我們看一看如何發(fā)送和接收數(shù)據(jù)

  客戶端的xml信息是由一個(gè)<command>元素和一些子元素組成:<commandtext>元素包含了存儲(chǔ)過程的名稱,<returnsdata>元素告訴服務(wù)器,客戶端是否要求接收返回?cái)?shù)據(jù),<param>元素包含參數(shù)信息。如果不使用參數(shù)的話,那么最簡單的發(fā)送字符串查詢就象下面這樣:

  <command>
   <commandtext>

  存儲(chǔ)過程或動(dòng)態(tài)sql語句

  </commandtext>
   <returnsvalues>true</returnsvalues>
  </command>

  你可以為每一個(gè)參數(shù)使用一個(gè)<param>元素,來添加參數(shù)。每個(gè)<param>元素有五個(gè)子元素:name,type,direction,size和value。子元素的順序可以隨意調(diào)換,但是所有的元素都應(yīng)當(dāng)有不能缺少,我通常按照定義一個(gè)ado對(duì)象的值的順序來定義它們。舉例來說,custorderhist存儲(chǔ)過程需要一個(gè)customid參數(shù),所以用來創(chuàng)建發(fā)送到getdata.asp的xml字符串的代碼為:

  dim s
   s = "<?xml version=""1.0

,歡迎訪問網(wǎng)頁設(shè)計(jì)愛好者web開發(fā)。|||""?>" & vbcrlf
   s = s & "<command><commandtext>"
   s = s & "custorderhist"
   s = s & "</commandtext>"
   s = s & "<returnsdata>" &true</returnsdata>"
   s = s & "<param>"
   s = s & "<name>customerid</name>"
   s = s & "<type><%=advarchar%></type>"
   s = s & "<direction>" & <%=adparaminput%></direction>"
   s = s & "<size>" & len(customerid)& "</size>"
   s = s & "<value>" & customerid &"</value>"
   s = s & "</param>"
   s = s & "</command>"

  注意,前面的代碼都是客戶端代碼,ado常量是不在客戶端定義的-這就是它們?yōu)槭裁词褂茫? %>標(biāo)記圍起來的原因。服務(wù)器在發(fā)送響應(yīng)之前使用正確的值取代它們。getdata.asp頁有一個(gè)response.contenttype,它的屬性為"text/xml",這樣,你就可以使用responsexml屬性來返回結(jié)果了。當(dāng)請(qǐng)求返回紀(jì)錄,你就可以創(chuàng)建一個(gè)recordset對(duì)象并且使用xmlhttp來打開它:

  dim r
   set r = createobject("adodb.recordset")
   r.open xhttp.responsexml

  當(dāng)查詢語句返回?cái)?shù)據(jù)時(shí),通過設(shè)置xmlhttprequest對(duì)象的responsexml屬性來創(chuàng)建一個(gè)domdocument:

  dim xml
   set xml = xhttp.responsexml

  輸出參數(shù)的xml字符串的每個(gè)返回值都包含一個(gè)元素,它們都是根元素<values>的直接子元素,例如:

  <?xml version=""1.0"" encoding=""gb2312""?>
  <values>
  <paramname>value</paramname>
   <paramname>value</paramname>
  </values>

  如果你的數(shù)據(jù)使用別的國家的文字,你可能需要把編碼屬性用相應(yīng)的編碼替換,例如對(duì)于大部分歐洲語言,可以使用iso-8859-1

  客戶端頁面使用返回的數(shù)據(jù)來格式化一個(gè)html字符串用于顯示,如:

  document.all("details").innerhtml = <一些格式化的html字符串>

  前面我們已經(jīng)介紹了使用asp和xml混合編程,那是因?yàn)閍sp頁面能夠很容易讓我們看清應(yīng)用程序正在做什么,但是你如果你不想使用asp的話,你也可以使用任何你熟悉的技術(shù)去創(chuàng)建一個(gè)客戶端程序。下面,我提供了一段vb代碼,它的功能和asp頁面一樣,也可以顯示相同的數(shù)據(jù),但是這個(gè)vb程序不會(huì)創(chuàng)建發(fā)送到服務(wù)器的xml字符串。它通過運(yùn)行一個(gè)名叫initialize的存儲(chǔ)過程,從服務(wù)器取回xml字符串,來查詢clientcommands表的內(nèi)容。

  clientcommands表包括兩個(gè)域:command_name域和command_xml域。客戶端程序需要三個(gè)特定的command_name域:getcustomerlist,custorderhist和recentpurchasebycustomerid。每一個(gè)命令的command_xml域包括程序發(fā)送到getdata.asp頁面的xml字符串,這樣,就可以集中控制xml字符串了,就象存儲(chǔ)過程名字所表現(xiàn)的意思一樣,在發(fā)送xml字符串到getdata.asp之前,客戶端程序使用xml dom來設(shè)置存儲(chǔ)過程的參數(shù)值。我提供的代碼,包含了用于定義initialize過程和用于創(chuàng)建clientcommands表的sql語句。

  我提供的例程中還說明了如何使用xhttprequest對(duì)象實(shí)現(xiàn)我在本文一開始時(shí)許下的承諾:任何遠(yuǎn)程的機(jī)器上的應(yīng)用程序都可以訪問getdata.asp;當(dāng)然,你也可以通過設(shè)置iis和ntfs權(quán)限來限制訪問asp頁面;你可以在服務(wù)器上而不是客戶機(jī)上存儲(chǔ)全局應(yīng)用程序設(shè)置;你可以避免通過網(wǎng)絡(luò)發(fā)送數(shù)據(jù)庫用戶名和密碼所帶來的隱患性。還有,在ie中,應(yīng)用程序可以只顯示需要的數(shù)據(jù)而不用刷新整個(gè)頁面。



收集最實(shí)用的網(wǎng)頁特效代碼!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 小金县| 英山县| 理塘县| 岱山县| 克什克腾旗| 文登市| 句容市| 茌平县| 庆城县| 绥阳县| 岱山县| 五大连池市| 垫江县| 甘谷县| 阳城县| 阳江市| 灵宝市| 沂水县| 镇江市| 浪卡子县| 曲周县| 溆浦县| 固安县| 沅江市| 包头市| 林芝县| 新河县| 嘉禾县| 万盛区| 吉林市| 祁东县| 玉门市| 哈巴河县| 温州市| 镇江市| 庆城县| 靖宇县| 旌德县| 洛宁县| 景谷| 繁昌县|