javascript|web|xml|資料|網頁
B/S結構的程式每執行一個操作往往都需要重新整理頁面,在重新整理過程中,伺服器不但要將資料發送到用戶端,還需要將一些格式資訊,比如說表格、圖片、標題等重新發送,佔用了大量頻寬。儘管IE提供了頁面緩衝的功能,但對於時刻發生變化的動態網頁,本機快取基本上不起什麼作用。如果能夠讓Web伺服器只傳送關鍵資料,不傳送格式就可以減少頻寬佔用。當然,在我的系統開發過程中,使用了智慧卡進行關鍵資料加、解密,出於速度考慮,儘可能減少被加密的資料就可以提高資訊的顯示速度。
我們可以使用微軟提供的webservice.htc實現通過JavaScript調用WebService,同時利用XML和XSL實現資料與格式相分離。主要技術要點如下:
一、WebService的調用:
首先從微軟網站上下載webservice.htc,使用方法就不說了,網上有詳細的調用說明。在網頁BODY中添加一個DIV,實現對webservice.htc的引用,如下:
<div id="htcWService" style="BEHAVIOR: url( ../../global/webservice.htc)"></div>
同時添加兩個DIV,用來顯示錯誤資訊以及結果資訊:
<DIV class="homemed" id="SearchResult"><b>說明:</b>輸入戶號,用滑鼠點擊“檢索”按鈕開始檢索。</DIV>
<DIV class="homemed" id="ErrorMessage"></DIV>
編寫JavaScript,實現對WebService的引用:
function openWebService()
{
htcWService.useService("../../WebServices/Garkcx.asmx?WSDL","Garkcx");
}
WebService返回經過編碼的XML(在這裡我們對資訊進行了智慧卡加密),在用戶端解碼後,我們可以藉助MSXML實現對XML解析以備並進行格式處理。
二、非同步呼叫WebService,解析XML
聲明兩個變數,用來儲存ActiveX對象:
var objXMLData; //儲存要解析的 XML 文檔
var objXMLStyle; //儲存 XSLT STYLE
通過JavaScript調用WebService的代碼如下:
function doSearch()
{
var iCallID;
iCallID = htcWService.Garkcx.callService(dataArrived, "DoSearch", strUserGUID, strSearchMethod, strDataBaseName, strSearchCondition, encodeMethod);
}
因為是非同步呼叫,所以當遠程服務調用完成後會觸發dataArrived方法。”DoSearch”後的內容是調用WebService所跟的參數。下面我們看看dataArrived代碼:
function dataArrived(objResult)
{
if(objResult.error)
{
var strErrorCode = objResult.errorDetail.code;
var strErrorMsg = objResult.errorDetail.string;
var strErrorRaw = objResult.errorDetail.raw;
document.all('ErrorMessage').innerHTML = '<b>* 錯誤 -</b> 無法找到指定社會安全號碼的使用者。<br />' + strErrorMsg;
}
else
{
try
{
objXMLData = new ActiveXObject('MSXML2.FreeThreadedDOMDocument');
}
catch(e){}
// 判斷解析器對象是否可以使用
if (objXMLData == null)
{
document.all('ErrorMessage').innerHTML = '* <b>錯誤: 不正確的 XML 解析器版本.</b><br />';
return;
}
//此處有一些解碼的代碼,省略
strResult = objResult.value;
// 事件不斷被觸發,檢測XML資料是否裝載完成
objXMLData.onreadystatechange = dataLoaded;
objXMLData.validateOnParse = true;
objXMLData.async = true;
// 裝載從 Web Service 返回的結果
objXMLData.loadXML(strResult);
}
}
function dataLoaded()
{
// 非同步訪問,如果 XML 解析器的 readyState 屬性為 4, 表示裝載結束。
if (objXMLData.readyState == 4)
{
if (objXMLData.parseError.errorCode != 0)
// 裝載過程出現錯誤
document.all('ErrorMessage').innerHTML = '<b>* 錯誤</b> - 無法解析 XML 資料結果.';
else
{
document.all('SearchResult').innerHTML = '';
ApplyXslStyle(); // 應用 XSLT 樣式
}
}
}
下面將傳遞過來的XML應用XSL樣式並顯示在IE瀏覽器中,這是通過調用ApplyXslStyle()方法實現的。該方法使用“MSXML2.XSLTemplate”組件實現解析操作。因為XSL樣式通常不會發生變化,所以本機快取有助於提高XSL訪問效率。代碼如下:
function ApplyXslStyle()
{
objXMLStyle = new ActiveXObject('MSXML2.FreeThreadedDOMDocument');
objXMLStyle.async = false;
objXMLStyle.resolveExternals = false;
strXslt = '../../XSLT/Czrk.xsl';
objXMLStyle.load(strXslt);
if (objXMLStyle.readyState == 4)
{
if (objXMLStyle.parseError.errorCode != 0)
document.all('ErrorMessage').innerHTML = '<b>* 錯誤</b> - 無法解析 XSLT 格式.';
else
{
document.all('SearchResult').innerHTML = '';
// 格式化並輸出結果
DisplayResult();
}
}
}
function DisplayResult()
{
// 建立一個新的 XSLTemplate 對象並設定樣式表
var objTemplate = new ActiveXObject('MSXML2.XSLTemplate');
objTemplate.stylesheet = objXMLStyle;
// 建立處理器來處理 XML 資料
var objProc = objTemplate.createProcessor();
// 指明使用的 XML 資料對象
objProc.input = objXMLData;
// 應用 XSL 樣式,並將結果賦值給字串
if (objProc.transform() == true)
{
var strResult = objProc.output
document.all('SearchResult').innerHTML = strResult;
}
else
document.all('ErrorMessage').innerHTML = '<b>* 錯誤</b> - 無法對查詢結果應用 XSLT 格式.';
}
這樣,通過WebService傳遞過來的XML資料就經過XSL格式處理後顯示在IE裡面。下面給出幾個截圖:
圖片(1)檢索資料前
..............................................................................................
圖片(2)檢索資料後
..............................................................................................
圖片(3)自訂檢索條件
posted on 2004-07-17 23:57 呂震宇 閱讀(8394) 評論(26) 編輯 收藏 引用 網摘 所屬分類: Web Form 編程
評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-07-18 13:52 Rover 不錯,建議別用document.all來引用,最好用documeng.getElementById('控制項ID')來引用,遵循w3c,還有相關的資料嗎?給個連結或者資料什麼的?一篇看著不過癮 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-07-18 13:59 香辣教師 用WebService Behavior有一些局限性,只有IE 5.0,IE 5.5,IE 6.0,IE 6.0 SP1支援,其他的瀏覽器都不支援,最近的Windows XP SP2上面的IE 6.0好像也禁用Behavior了。而且它不能垮域調用的Web Service。所以不能把WebForm和Web Service來分開部署。 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-07-18 15:24 呂震宇
相關資料的話,可以參考《ASP.NET分散式資料庫應用程式進階編程》,Alex Homer DaveSussman著,清華大學出版社出版。
實際上,我這裡僅僅是將項目中的一小部分摘錄出來而已。當一個訪問請求到達網站時,我先通過代碼測試用戶端IE瀏覽器版本以及是否支援JavaScript(代碼見下),如果發現用戶端不支援的話,那沒將導向另外一個頁面,這個頁面將在伺服器端將XML與XSL產生HTML(如何用C#代碼實現對XML的XSL格式處理就不用多說了吧),然後將結果返回給使用者,不過效能肯定收到影響。因為出於系統安全等方面的考慮,在我的系統中,使用這種方式檢索的資訊是受到限制的。
用戶端是否支援JavaScript的檢測代碼:
<%@ Page Language="C#" EnableSessionState="False"%>
<%
String strClientType = Request.QueryString["client"];
%>
<html>
<head>
<meta http-equiv="refresh" content="1;url=no-client-script.aspx?client=<% = strClientType %>" />
<title>檢測用戶端是否支援 Script 指令碼</title>
<script language="JavaScript">
<!--
function jumpScripting() {
// jump to page using client-side JavaScript - if jump not executed
// then client does not have scripting available or it is disabled
window.location.href='SearchForm/<% = strClientType %>/default.htm';
}
//-->
</script>
</head>
<body onload="jumpScripting()">
<font size="2" face="宋體">檢測用戶端是否支援 Script 指令碼 </font>
</body>
</html>
檢測用戶端類型的代碼:
public int ClientType() {
// return an integer indicating the type of device
// 0 = Not Supported by Application
// 1 = HTML 3.2. client
// 2 = Internet Explorer 4
// 3 = Internet Explorer 5 or above
// 4 = Small Screen HTML ( < 50 chars per line or < 400px wide)
// 5 = WML Supporting Device (i.e. cellphone)
// 9 = Error While Detecting Type
// create integer variable to hold client type
int intType;
try {
// get reference to Browser Capabilities
System.Web.Mobile.MobileCapabilities objBCaps
= (System.Web.Mobile.MobileCapabilities) Request.Browser;
// check the preferred rendering type of the device
String strRenderType = objBCaps.PreferredRenderingType.ToLower();
if (strRenderType.IndexOf("wml") != -1)
intType = 5; // type is WML device
else if (strRenderType.IndexOf("html") != -1) {
intType = 1; // assume it's an HTML 3.2 device
// next check the screen size
if (objBCaps.ScreenPixelsWidth < 400 || objBCaps.ScreenCharactersWidth < 50)
intType = 4; // it's a small screen HTML device
else {
// assume it's a normal browser - check if its IE
if (objBCaps.Browser == "IE") {
// check the version number
if (objBCaps.MajorVersion >= 5)
intType = 3; // IE 5.x or above
else if (objBCaps.MajorVersion == 4)
intType = 2; // IE 4.x
}
}
}
else // not WML or HTML
intType = 0; // not recognized or supported
}
catch(Exception objErr) {
intType = 9; // error during detection
}
return intType;
}
首頁Default.aspx代碼:
<%@ Page Language="C#"%>
<!-- register the user control that contains the detection code -->
<%@Register TagPrefix="GARK" TagName="GetClientType" Src="global/client-detect.ascx" %>
<!-- insert user control into the page -->
<GARK:GetClientType id="ClientDetect" runat="server" />
<script language="C#" runat="server">
void Page_Load() {
switch (ClientDetect.ClientType()) {
case 0: // not supported
Response.Clear();
Response.ContentType = "text/text";
Response.Write("Sorry, this application does not support your client type: " + Request.UserAgent);
Response.End();
break;
case 2: // IE 4.x
Response.Clear();
Response.Redirect("client-script-check.aspx?client=ie4");
Response.End();
break;
case 3: // IE 5.x and above
Response.Clear();
Response.Redirect("client-script-check.aspx?client=ie5");
Response.End();
&nb, sp; break;
case 4: // small-screen HTML device or WML client
case 5:
Response.Clear();
Server.Transfer("SearchForm/mobile/default.aspx");
break;
default: // assume HTML 3.2 client
Response.Clear();
Response.Redirect("client-script-check.aspx?client=html32");
Response.End();
break;
}
}
</script>
回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-07-21 13:57 一點一滴 這個web服務怎麼進行驗證呢? 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-07-21 14:32 呂震宇 我沒有考慮使用現有驗證(Form驗證、Windows驗證等),而是將驗證放在了智慧卡中,在用戶端與伺服器間傳送的關鍵資料是經過簽名並加密的,系統通過對這個加密資訊的驗證進而實現對使用者身份的驗證。智慧卡中的密鑰是永遠也讀不出來的,而且智慧卡從制卡到密鑰分發到傳送等都有一套規範的體系。 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-08-25 17:21 beloved 在MSDN上可以看出,微軟在很早以前就已經放棄對webservices.htc的支援了。
最要命的是現在裝了IE SP2的機器對調用ActiveX進行了限制,每次你在客戶建立一個Object的時候都會提示你。這樣很是不爽。不知道有沒有更好的辦法來解決這個問題。 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-08-25 22:18 呂震宇 @beloved
誰也限制不了微軟改變策略。我想微軟大概將程式員趕向.net平台以及智能用戶端吧。我想Flex、智能用戶端以及未來微軟基於XML的代碼開發恐怕會佔主導地位。雖然這可以解決上述問題,但我們不得不學習、學習再學習了... 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-09-10 09:10 賞梅齋 看到你的文章受益頗多,覺得這種方式被微軟所放棄有點可惜. 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-09-14 10:17 aspsir 關於驗證,最基本的可以使用Session來驗證,同時通過WEB SERVICE的EnableSession=true來使WebMethod支援Session 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-09-19 08:25 luoluo 這個方面flash是更好的選擇,比ms jscript有更好的跨平台性,flash對xml和webservice都有很好的支援。 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-09-19 12:55 呂震宇 我想Macromedia 的flex以及微軟提倡的智能用戶端在這方面都有很好的前景 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2004-09-27 08:40 賞梅齋 不過,感覺微軟提倡的智能用戶端過於重量級,對於輕型應用似於過於複雜. 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-02-23 02:52 PuzzledJavascriptMan 如果伺服器端Webservice是Java寫的,Javascript代碼怎麼寫呀? 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-02-23 12:20 呂震宇 這個我就不清楚了。因為不能使用webservice.htc。不過你可以下載webservice.htc,然後研究一下裡面的JavaScript代碼,應當有所協助。 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-03-18 14:32 cxuqiang 留下手印。。。。 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-04-09 03:21 一滴水 好搞深!! 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-06-10 18:23 li 我用的是Windows XP SP2上面的IE 6.0,有許多網頁無法瀏覽,且無法觀看視頻,必須更換版本嗎? 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-07-11 15:40 拙劣的程式員 研究研究 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-09-01 13:10 tonyzhang 如果這種方式只能用微軟的東東開發的webservices那也太有局限性了。我用java+axis開發的webservice按照微軟官方網站提供的方式進行了實驗,沒有成功。 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-11-03 09:37 bobox 本來是抱著很幸運的心情來看這篇文章的,因為看道htc感覺發現了我需要的鑰匙。但是看完以上評述後,心又冷了。
ms webservice既然又慢。而且對真正異構系統的支援又這麼爛。似乎只有用ms自己的產品系列的用戶端才對它有很好的支援,微軟提供了一個不錯的代理。失望之情不言而喻啊。。。
回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-11-28 15:04 白菜 有人說XP的SP2限制了這個東西?
我怎麼沒感覺到... 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-12-02 15:39 Oxygen 可以垮域,不過就是有提示,現在所有的方法,都是有提示的. 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2005-12-02 15:39 Oxygen 可以垮域,不過就是有提示,現在所有的方法,都是有提示的. 回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2006-04-24 10:48 sac 那麼在sp2下面能不能使用呢?
我使用的時候總是提示useService不是方法
回複 更多評論
# re: 用JavaScript與WebService實現網頁部分資料XML傳送 2006-05-29 11:17 e旋風 我也是使用這種
怎麼代碼執行完 // 裝載從 Web Service 返回的結果
objXMLData.loadXML(strResult);
就不再執行function dataLoaded() 了呢 回複 更多評論