用XMLHTTP實現僞Web服務

本文揭示XMLHTTP的神祕面紗。我很喜歡使用XMLHTTP,主要是因爲它能夠將任何ActiveX類方法展示給客戶。就是說,你能夠讓客戶調用你的ActiveX控件。

===========================================================
本文揭示XMLHTTP的神祕面紗。我很喜歡使用XMLHTTP,主要是因爲它能夠將任何ActiveX類方法展示給客戶。就是說,你能夠讓客戶調用你的ActiveX控件。最主要的是所有的通訊都是在後臺進行的。使用XMLHTTP能夠擴展對數據庫的存取能力。提交查詢申請時,用XMLHTTP向ASP偵聽(服務)頁發出XML格式的指令,ASP網頁隨即解釋該命令並調用VB activeX控件裏的方法。這個VB控件用XML字符串形式將查詢結果返回給ASP服務頁,再由服務頁將結果組裝成XML格式返回給用戶。在作這一系列事情時,不需對當前網頁進行重加載。用戶甚至不知道後臺在作些什麼。

在本文末尾可以下載有關示例源程序。

本文示例對系統的要求是:
MS SQL Server(包含pubs數據庫示例),
MS IE 5.0+,
MSXML 3.0解析器,
MS IIS - 將示例中所有的ASP文件,CSS,及mybooks.xml文件拷貝到服務器的一個虛路徑下。

將bookview.asp, xml_receive.asp, mybooks.xml, default.css, 和book.css等文件拷貝到服務器的一個虛路徑下。
在服務器上註冊WebClass.xmlcontrol(webclass.dll)。
在xml_receive.asp文件裏設置SQL Server服務器名。
在webClass.xmlcontrol類裏設置你的用戶名和口令。

來看看XMLHTTP的功能:

客戶端:這裏是bookViewer.asp文件中的一段代碼,用XMLHTTP來存取Pubs數據庫的books:
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //創建XMLHTTP對象
var xmlcmd='<?xml version="1.0"?><ENVELOPE><XMLCMD c1="gettitlesxml" p1="" p2="" p3=""></XMLCMD></ENVELOPE>';
xmlhttp.Open("POST","xml_receive.asp", false); //準備用XMLHTTP向xml_receive.asp發送指令
xmlhttp.Send(xmlcmd); //發出指令

第一行:創建XMLHTTP對象的引用。
第二行:創建XML指令。注意:可以不用XML格式而使用普通文件構造指令。之所以用XML格式,是因爲它容易解析指令本身和指令的參數。
第三行:打開連接。其中第一個參數是http方法(最常使用的不是"POST"就是"GET")。第二個參數指向執行指令的URL路徑。第三個參數決定是否異步執行。另外還可以加上二個參數,即用戶名和口令。在上面的例子中,我用HTTP POST呼叫xml_receive.asp網頁(我稱它爲偵聽頁),要求同步進行查詢工作(在完成查詢前不做其他事)。
第四行:發出指令,開始工作。注意:指令是由第二行代碼作出的。因爲使用了同步執行方式,現在只能坐等結果返回。

偵聽頁(xml_receive.asp)工作基礎
我把這個網頁稱爲偵聽頁,是因爲它在服務端坐等XMLHTTP指令的到來。收到查詢請求後,它要做三件事。
首先,將查詢請求加載到XML DOM,並對指令及其參數進行解析。
其次,根據客戶要求,調用後臺Active X控件的處理方法。後臺Active X控件將執行結果用XML字符串返回。
第三,將返回結果加載到XML DOM並用Response對象返回給用戶。
[譯者注:這是一種很典型的三層應用,可以舉一反三。]

以上三步驟具體執行如下:

偵聽頁(第一步 - 指令解析):
以下是xml_receive.asp文件中的一段代碼,後面附有註釋。這段代碼用於解析接收到的查詢指令和參數(parameter1, parameter2, parameter3)。參數的數量可以任意增加。

    var doc = Server.CreateObject("Msxml2.DOMDocument");
    doc.load(Request); //將XMLHTTP請求加載到XML DOM進行解析
    var c1=doc.childNodes.item(1).childNodes.item(0).attributes.item(0).text; //指令
    var p1=doc.childNodes.item(1).childNodes.item(0).attributes.item(1).text; //參數1
    var p2=doc.childNodes.item(1).childNodes.item(0).attributes.item(2).text; //參數2
    var p3=doc.childNodes.item(1).childNodes.item(0).attributes.item(3).text; //參數3
    if (doc.childNodes.item(1).childNodes.length==2) //檢驗xml
    var passedXML=''+doc.childNodes.item(1).childNodes.item(1).xml;
    var xmlreturn=''; //初始化返回值
    var doc=null; //釋放XML DOM

偵聽頁(第二步 - 調用後臺Active X控件的適當方法):
以下是xml_receive.asp文件中調用"gettitlesxml"方法的一段代碼。它創建Active X對象並調用其中的GetTitlesXML()方法來返回Pubs數據庫的查詢結果。記住,結果是用XML字符串方式返回。

//************* Function gettitlesxml ***********************
if (c1=="gettitlesxml")
{
   resultsXML=true; //加載結果的xml字符串
   var objWC= Server.CreateObject("WebClass.xmlControl"); //初始化VB控件
   objWC.strServer=sqlServer; //指向SQL Server服務器
   xmlreturn=objWC.GetTitlesXML(); //VB函數,用XML字符串返回標題
   var objWC=null; //釋放VB控件
}

偵聽頁(第三步 - 返回結果):
以下是xml_receive.asp文件中的一段代碼,將查詢結果返回給用戶。這裏包括創建結果DOM,加載結果到DOM,檢查加載是否正確,最後用ASP的Response對象將結果返回給用戶。注意:是用XML DOM的Save方法返回結果,其參數爲Response,表示將結果存入Response輸出流。

var result =  Server.CreateObject("Msxml2.DOMDocument"); //創建結果XML DOM

if (resultsXML) //加載XML字符串
{
   result.loadXML(xmlreturn); //調用loadXML將字符串加載到DOM
   if (c1=="savemybooks") result.save(Server.MapPath(p1)); //如果需要,保存XML文件
}

if ( result.parseError.errorCode!=0 ) //解析出錯
{
   //返回結果
   xmlreturn='<?xml version="1.0"?><RESULTS error="true">FALSE</RESULTS>';
   result.loadXML(xmlreturn); //將出錯信息加入到結果
}

//用ASP Response對象將結果返回給用戶
Response.ContentType = "text/xml"; //返回XML格式文件
result.save(Response);//將DOM存放到HTTPResponse輸出流
var result = null;

返回到客戶端(bookViewer.asp)
服務端工作時,客戶端只有耐心等待。一旦收到返回結果,就將其加載到XML DOM,並用ASP表單顯式。

objSallbooks.load(xmlhttp.responseXML); //將返回值加載到DOM
var xmlhttp = null;
//檢驗返回是否出錯
if (objSallbooks.childNodes.item(1).childNodes.item(0).nodeValue=="FALSE") Snumberofbooks=0;
else Snumberofbooks=(objSallbooks.childNodes.item(1).childNodes.length); //設置Books數量
if (Snumberofbooks>0)             display_book(0,1); //顯式第一本書籍名

第一行:將XMLHTTP的Response加載到XML DOM對象objSallBooks中去。XMLHTTP另外還有responseText方法用於加載普通文件。
第二行:因爲已經建立了XML DOM,可以不再需要XMLHTTP了。
第三行:如果出錯,偵聽頁會返回<?xml version="1.0"?><RESULTS error="true">FALSE</RESULTS>出錯信息。
第四行:如果正確,DOM裏就有查詢結果,並可通過根節點的子節點長度求得結果數量。
第五行:如果有結果,就將結果綁定到表單上顯示。

現在可以對gettitlesxml函數作些補充。
對BookViewer.ASP文件作一些改動就能增強gettitlesxml函數的查詢功能。用戶可以根據書籍的類型,價格和銷售日期對書籍進行查詢。下面就是改動的代碼。注意文本框由原先的只讀方式改爲常規方式。

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
var where= "";
if(document.frmFields.Stype.value.length>0) where=where + " type= '"+document.frmFields.Stype.value+"' AND ";
if(document.frmFields.Sprice.value.length>0) where=where + " price<= "+document.frmFields.Sprice.value+" AND ";
if(document.frmFields.Ssales.value.length>0) where=where + " ytd_sales>= "+document.frmFields.Ssales.value;
if(where.length>0) where = " WHERE " + where;
var xmlcmd='<?xml version="1.0"?><ENVELOPE><XMLCMD c1="gettitlesxml" p1="'+where+'" p2="" p3=""></XMLCMD></ENVELOPE>'; xmlhttp.Open("POST", "xml_receive.asp", false);  //用XMLHTTP向xml_receive.asp傳送指令
xmlhttp.Send(xmlcmd);//發出XML指令

第二行到第六行:建立查詢語句
第七行:與原先的代碼不同在於增加了一個p1參數,它是由第二行到第七行代碼建立的。

xml_receive.ASP文件的改動:
將新增的p1參數加入到Active X控件的GetTitlesXML函數中。

//************* Function gettitlesxml ***********************
if (c1=="gettitlesxml")
{
   resultsXML=true; //加載結果的xml字符串
   var objWC= Server.CreateObject("WebClass.xmlControl"); //初始化VB控件
   objWC.strServer=sqlServer; //指向SQL Server服務器
   xmlreturn=objWC.GetTitlesXML(p1); //VB函數,用XML字符串返回結果
   var objWC=null; //釋放VB控件
}

結語
這裏所作的一切是爲了將ASP的客戶互動應用技術提高一個檔次。用戶能夠在一個簡單的網頁裏訪問數據庫。查詢過程由XMLHTTP在後臺執行,給用戶的感覺就象在用一個Windows程序而不是Web應用。本文涉及的是Web服務理念。比Web服務更爲複雜的是SOAP協議,它能使Web服務更具有彈性。在一般情況下 (只要不是分佈式應用),用上面給出的方法是足夠的了。

按照上面描述的技術路線:
 客戶端應用-->ASP偵聽頁-->Active X控件,以及Active X控件-->ASP偵聽頁-->客戶端應用
提供的方法,可以在客戶端和後臺Active X控件之間建立通訊聯繫。ASP的偵聽頁可以給出用戶需要的Active X控件的部分方法和屬性,而將其他內容隱藏起來。在偵聽頁中可以建立加密機制。這樣可以使得整個數據庫安全性得到很大程度的提高。因爲所有對數據庫的訪問都是通過Active X進行的,只要一些必需的訪問函數暴露在ASP文件中。

附件:Http://www.ChinaOk.net/down/200204150806170.zip

發佈了29 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章