一个调用ATL Server WebServices 的AJAX客户端

王朝other·作者佚名  2006-12-15
窄屏简体版  字體: |||超大  

请将下面的代码完整复制到soapclient.js中

/**//*****************************************************************************

AJAX

Javascript "SOAP Client" library

Thank to Mr.Matteo Casati, Ihar Voitka - http://www.guru4.net/

Author: ZhangLiang, E-Mail:cheungmine@gmail.com

Date: 2006-8-31

*****************************************************************************/

function _debug(rownum, msg) ...{ alert(rownum+":"+msg); }

var SOAP_SUCCESS = 0;

var SOAP_FAULT = 1;

var _sr_env_hdr_ = "<soap:Envelope " +

"xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" " +

"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" " +

"xmlns:xsd="http://www.w3.org/2001/XMLSchema" " +

"xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">";

var _sr_body_hdr_ = "<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">";

var _soap_header_m_token_ = ""; // global varible, soap_header: m_token

function SOAPParams(callid, url, method, async, callback, username, password)

...{

this.callid = callid;

this.url = url; // "http://localhost/MtkWebgisServer/MtkWebgis.dll?Handler=GenMtkWebgisWSDL";

this.svc = null; //"http://cl2/MtkWebgisServer/MtkWebgis.dll?Handler=Default"; // 未完

this.method = method;

if (async+"" == "undefined")

this.async = true; // default value

else

this.async = async;

if (this.async)...{

if (callback+"" == "undefined")

this.callback = soap_callback;

else

this.callback = callback;

}

this.username = null;

if (username+"" != "")

this.username = username;

this.password = null;

if (password+"" != "")

this.password = password;

this.wsdl = null;

this.result = SOAP_FAULT;

this.xmlhttp = null; // xmlhttp object returned

this._pl = new Array(); // input parameters list

this.add = function(name, value)...{

this._pl[name] = value;

return this;

}

this.toXml = function()...{

var xml = "";

for(var p in this._pl)...{

var t = typeof(this._pl[p]);

if (t == "object" || t == "function")

xml += "<" + p + ">" + this._pl[p].toXml() + "</" + p + ">";

else

xml += "<" + p + ">" + this._pl[p].toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</" + p + ">";

}

return xml;

}

this.setToken = function()...{

if (this.method=="login")...{

_soap_header_m_token_ = this.getval("snp:m_token");

}

}

this.getToken = function()...{

return _soap_header_m_token_;

}

this.getval = function(name)...{

var ret = SOAPClient._getElementsByTagName(this.xmlhttp.responseXML.documentElement, name).item(0);

return ret.text;

}

this.retval = function()...{

return this.getval("return");

}

// SOAP:Fault

this.faultcode = function()...{

return this.getval("faultcode");

}

this.faultstring = function()...{

return this.getval("faultstring");

}

this.faultdetail = function()...{

return this.getval("detail");

}

}

function SOAPClient()...{}

SOAPClient.invoke = function(params)

...{

params.result = SOAP_FAULT;

if(params.async)

SOAPClient._loadWsdl(params);

else

return SOAPClient._loadWsdl(params);

}

// private: wsdl cache

SOAPClient_cacheWsdl = new Array();

// private: invoke async

SOAPClient._loadWsdl = function(params)

...{

// load from cache?

params.wsdl = SOAPClient_cacheWsdl[params.url];

if(params.wsdl + "" != "" && params.wsdl + "" != "undefined")...{

params.svc = SOAPClient._getService(params.wsdl);

return SOAPClient._sendSoapRequest(params);

}

// get wsdl

var _xmlhttp = SOAPClient._getXmlHttp();

if (params.username+"" != "undefined")

_xmlhttp.open("GET", params.url, params.async, params.username, params.password);

else

_xmlhttp.open("GET", params.url, params.async);

if(params.async)...{

_xmlhttp.onreadystatechange = function()...{

if(_xmlhttp.readyState == 4)

SOAPClient._onLoadWsdl(params, _xmlhttp);

}

}

_xmlhttp.send(null);

if (!params.async)

return SOAPClient._onLoadWsdl(params, _xmlhttp);

}

SOAPClient._onLoadWsdl = function(params, req)

...{

if (req.readyState == 4 && req.status == 200)...{

params.wsdl = req.responseXML;

params.svc = SOAPClient._getService(params.wsdl);

SOAPClient_cacheWsdl[params.url] = params.wsdl; // save a copy in cache

return SOAPClient._sendSoapRequest(params);

}

return SOAP_FAULT;

}

SOAPClient._sendSoapRequest = function(params)

...{

// get namespace, ok

var ns = SOAPClient._getAttribValue(params.wsdl.documentElement, "targetNamespace");

// 构造SOAP请求, SOAP 2.0

var sr = _sr_env_hdr_ + "<soap:Header><snp:m_token xmlns:snp=""+ns+"">" +

_soap_header_m_token_ + "</snp:m_token></soap:Header>" +

_sr_body_hdr_ + "<snp:" + params.method + " xmlns:snp="" + ns + "">" +

params.toXml() + "</snp:" + params.method + "></soap:Body></soap:Envelope>";

// send request

params.xmlhttp = SOAPClient._getXmlHttp();

params.xmlhttp.open("POST", params.svc, params.async);

params.xmlhttp.setRequestHeader("SOAPAction", ""#"+params.method+"""); // SOAPAction: "#HelloWorld"

params.xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");

if(params.async)...{

params.xmlhttp.onreadystatechange = function()...{

if(params.xmlhttp.readyState == 4)

SOAPClient._onSendSoapRequest(params);

}

}

try...{

params.xmlhttp.send(sr);

}

catch(ex)...{}

if (!params.async)

return SOAPClient._onSendSoapRequest(params);

}

SOAPClient._onSendSoapRequest = function(params)

...{

if (params.xmlhttp.readyState == 4 && params.xmlhttp.status == 200)...{

params.result = SOAP_SUCCESS; // 未完...

params.setToken(); // 设置全局变量: _soap_header_m_token_

}

if(params.async && params.callback)

params.callback(params.result, params);

if (!params.async)

return params.result;

}

// private: utils

SOAPClient._getElementsByTagName = function(document, tagName, ns)

...{

try...{

// trying to get node omitting any namespaces (latest versions of MSXML.XMLDocument)

var lst = document.selectNodes(".//*[local-name()=""+ tagName +""]");

if (lst.length == 0)

throw 0;

return lst;

}

catch (ex)...{}

// old XML parser support

if (ns+"" == "undefined")

return document.getElementsByTagName(tagName);

return document.getElementsByTagName(ns+":"+tagName);

}

SOAPClient._getService = function(wsdl)

...{

var soap_address = SOAPClient._getElementsByTagName(wsdl.documentElement, "address", "soap").item(0);

return SOAPClient._getAttribValue(soap_address, "location");

}

SOAPClient._getAttribValue = function(node, name)

...{

return (node.attributes[name]+"" == "undefined") ? node.attributes.getNamedItem(name).nodeValue : node.attributes[name].value;

}

// private: xmlhttp factory

SOAPClient._getXmlHttp = function()

...{

try...{

if(window.XMLHttpRequest)...{

var req = new XMLHttpRequest();

// some versions of Moz do not support the readyState property and the onreadystate event so we patch it!

if(req.readyState == null)

...{

req.readyState = 1;

req.addEventListener("load",

function()

...{

req.readyState = 4;

if(typeof req.onreadystatechange == "function")

req.onreadystatechange();

},

false);

}

return req;

}

else if(window.ActiveXObject) ...{

return new ActiveXObject(SOAPClient._getXmlHttpProgID());

}

}

catch (ex) ...{}

throw new Error("Your browser does not support XmlHttp objects");

}

SOAPClient._getXmlHttpProgID = function()

...{

if(SOAPClient._getXmlHttpProgID.progid)

return SOAPClient._getXmlHttpProgID.progid;

var progids = ["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];

var o;

for(var i = 0; i < progids.length; i++)

...{

try

...{

o = new ActiveXObject(progids[i]);

return SOAPClient._getXmlHttpProgID.progid = progids[i];

}

catch (ex) ...{};

}

throw new Error("Could not find an installed XML parser");

}

假设ATL XML WebServices实现方法如下:

[id(1), helpstring("登入系统, 获得用户令牌和全图URL, 以后任何方法调用必须给出令牌")]

HRESULT login([in] BSTR Username, [in] BSTR Password);

id(2), helpstring("刷新地图, 取地图imgURL")]

HRESULT refresh([out] DOUBLE* Scale, [out, retval] BSTR *imgURL);

客户端IE中调用如下:

<HTML>

<HEAD>

<TITLE>WebGis Demo Page - WebGis AJAX Client</TITLE>

<script language="javascript" src="ajax/soapclient.js"></script>

<script language="javascript">

// WebService URL

var g_url = "http://cl2/mtkwebgis/MtkWebgis.dll?Handler=GenMtkWebgisWSDL";

function soap_callback(rcode, params)

...{

if (rcode == SOAP_SUCCESS)

...{

switch (params.callid)

...{

case "刷新":

imgMap.src = params.retval(); // retval() 取得[out,retval]参数

alert( "当前比例:" + params.getval("Scale") ); // getval(...) 取得[out]参数

break;

}

}

else

...{

alert(params.callid+":发生错误");

}

}

function Login()

...{

// 同步调用, 获得令牌

var soap = new SOAPParams("登录", g_url, "login", false);

soap.add("Username", "cheung");

soap.add("Password", "mine");

if (SOAP_SUCCESS == SOAPClient.invoke(soap))

refresh();

else

alert("登录失败");

}

function Refresh()

...{

// 异步调用刷新, 默认回调函数soap_callback

var soap = new SOAPParams("刷新", g_url, "refresh");

SOAPClient.invoke(soap);

}

</script>

</HEAD>

<BODY onload="Login();">

<div id="divMap"><img id="imgMap"></div>

</BODY>

</HTML>

使用soapclient.js需要注意,我假设XML WebServices必须存在如上面所示的login方法,用于验证用户,而且m_token必须是soap头。login原型如下:

[ soap_method ]

[ soap_header( value = "m_token", out = true ) ]

HRESULT login(/**//*[in]*/ BSTR Username, /**//*[in]*/ BSTR Password)

...{

CHAR szID[MAX_TOKEN_LEN + 1];

*szID = 0;

DWORD dwSize = MAX_TOKEN_LEN;

HRESULT hr = m_spSessionSvc->CreateNewSession(szID, &dwSize, &m_spSession);

CHECK_FAILED(hr);

szID[dwSize] = 0;

m_token = CComBSTR(szID).Detach();

return hr;

}

这样,用户就可以通过soapclient.js在IE中直接调用ATL Server写的XML WebServices了。

(本文写于2006年9月,cheungmine,上海新区时空信息技术有限公司)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航