请将下面的代码完整复制到soapclient.js中
/**/
/*****************************************************************************
AJAX
Javascript"SOAPClient"library
ThanktoMr.MatteoCasati,IharVoitka-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:Bodysoap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> " ;
var _soap_header_m_token_ = "" ; // globalvarible,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;//defaultvalue
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;//xmlhttpobjectreturned
this._pl=newArray();//inputparameterslist
this.add=function(name,value)...{
this._pl[name]=value;
returnthis;
}
this.toXml=function()...{
varxml="";
for(varpinthis._pl)...{
vart=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,"&").replace(/</g,"<").replace(/>/g,">")+"</"+p+">";
}
returnxml;
}
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)...{
varret=SOAPClient._getElementsByTagName(this.xmlhttp.responseXML.documentElement,name).item(0);
returnret.text;
}
this.retval=function()...{
returnthis.getval("return");
}
//SOAP:Fault
this.faultcode=function()...{
returnthis.getval("faultcode");
}
this.faultstring=function()...{
returnthis.getval("faultstring");
}
this.faultdetail=function()...{
returnthis.getval("detail");
}
}
function SOAPClient() ... {}
SOAPClient.invoke = function (params)
... {
params.result=SOAP_FAULT;
if(params.async)
SOAPClient._loadWsdl(params);
else
returnSOAPClient._loadWsdl(params);
}
// private:wsdlcache
SOAPClient_cacheWsdl = new Array();
// private:invokeasync
SOAPClient._loadWsdl = function (params)
... {
//loadfromcache?
params.wsdl=SOAPClient_cacheWsdl[params.url];
if(params.wsdl+""!=""&¶ms.wsdl+""!="undefined")...{
params.svc=SOAPClient._getService(params.wsdl);
returnSOAPClient._sendSoapRequest(params);
}
//getwsdl
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)
returnSOAPClient._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;//saveacopyincache
returnSOAPClient._sendSoapRequest(params);
}
returnSOAP_FAULT;
}
SOAPClient._sendSoapRequest = function (params)
... {
//getnamespace,ok
varns=SOAPClient._getAttribValue(params.wsdl.documentElement,"targetNamespace");
//构造SOAP请求,SOAP2.0
varsr=_sr_env_hdr_+"<soap:Header><snp:m_tokenxmlns: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>";
//sendrequest
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)
returnSOAPClient._onSendSoapRequest(params);
}
SOAPClient._onSendSoapRequest = function (params)
... {
if(params.xmlhttp.readyState==4&¶ms.xmlhttp.status==200)...{
params.result=SOAP_SUCCESS;//未完...
params.setToken();//设置全局变量:_soap_header_m_token_
}
if(params.async&¶ms.callback)
params.callback(params.result,params);
if(!params.async)
returnparams.result;
}
// private:utils
SOAPClient._getElementsByTagName = function (document,tagName,ns)
... {
try...{
//tryingtogetnodeomittinganynamespaces(latestversionsofMSXML.XMLDocument)
varlst=document.selectNodes(".//*[local-name()=""+tagName+""]");
if(lst.length==0)
throw0;
returnlst;
}
catch(ex)...{}
//oldXMLparsersupport
if(ns+""=="undefined")
returndocument.getElementsByTagName(tagName);
returndocument.getElementsByTagName(ns+":"+tagName);
}
SOAPClient._getService = function (wsdl)
... {
varsoap_address=SOAPClient._getElementsByTagName(wsdl.documentElement,"address","soap").item(0);
returnSOAPClient._getAttribValue(soap_address,"location");
}
SOAPClient._getAttribValue = function (node,name)
... {
return(node.attributes[name]+""=="undefined")?node.attributes.getNamedItem(name).nodeValue:node.attributes[name].value;
}
// private:xmlhttpfactory
SOAPClient._getXmlHttp = function ()
... {
try...{
if(window.XMLHttpRequest)...{
varreq=newXMLHttpRequest();
//someversionsofMozdonotsupportthereadyStatepropertyandtheonreadystateeventsowepatchit!
if(req.readyState==null)
...{
req.readyState=1;
req.addEventListener("load",
function()
...{
req.readyState=4;
if(typeofreq.onreadystatechange=="function")
req.onreadystatechange();
},
false);
}
returnreq;
}
elseif(window.ActiveXObject)...{
returnnewActiveXObject(SOAPClient._getXmlHttpProgID());
}
}
catch(ex)...{}
thrownewError("YourbrowserdoesnotsupportXmlHttpobjects");
}
SOAPClient._getXmlHttpProgID = function ()
... {
if(SOAPClient._getXmlHttpProgID.progid)
returnSOAPClient._getXmlHttpProgID.progid;
varprogids=["Msxml2.XMLHTTP.5.0","Msxml2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
varo;
for(vari=0;i<progids.length;i++)
...{
try
...{
o=newActiveXObject(progids[i]);
returnSOAPClient._getXmlHttpProgID.progid=progids[i];
}
catch(ex)...{};
}
thrownewError("CouldnotfindaninstalledXMLparser");
}
AJAX
Javascript"SOAPClient"library
ThanktoMr.MatteoCasati,IharVoitka-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:Bodysoap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> " ;
var _soap_header_m_token_ = "" ; // globalvarible,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;//defaultvalue
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;//xmlhttpobjectreturned
this._pl=newArray();//inputparameterslist
this.add=function(name,value)...{
this._pl[name]=value;
returnthis;
}
this.toXml=function()...{
varxml="";
for(varpinthis._pl)...{
vart=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,"&").replace(/</g,"<").replace(/>/g,">")+"</"+p+">";
}
returnxml;
}
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)...{
varret=SOAPClient._getElementsByTagName(this.xmlhttp.responseXML.documentElement,name).item(0);
returnret.text;
}
this.retval=function()...{
returnthis.getval("return");
}
//SOAP:Fault
this.faultcode=function()...{
returnthis.getval("faultcode");
}
this.faultstring=function()...{
returnthis.getval("faultstring");
}
this.faultdetail=function()...{
returnthis.getval("detail");
}
}
function SOAPClient() ... {}
SOAPClient.invoke = function (params)
... {
params.result=SOAP_FAULT;
if(params.async)
SOAPClient._loadWsdl(params);
else
returnSOAPClient._loadWsdl(params);
}
// private:wsdlcache
SOAPClient_cacheWsdl = new Array();
// private:invokeasync
SOAPClient._loadWsdl = function (params)
... {
//loadfromcache?
params.wsdl=SOAPClient_cacheWsdl[params.url];
if(params.wsdl+""!=""&¶ms.wsdl+""!="undefined")...{
params.svc=SOAPClient._getService(params.wsdl);
returnSOAPClient._sendSoapRequest(params);
}
//getwsdl
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)
returnSOAPClient._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;//saveacopyincache
returnSOAPClient._sendSoapRequest(params);
}
returnSOAP_FAULT;
}
SOAPClient._sendSoapRequest = function (params)
... {
//getnamespace,ok
varns=SOAPClient._getAttribValue(params.wsdl.documentElement,"targetNamespace");
//构造SOAP请求,SOAP2.0
varsr=_sr_env_hdr_+"<soap:Header><snp:m_tokenxmlns: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>";
//sendrequest
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)
returnSOAPClient._onSendSoapRequest(params);
}
SOAPClient._onSendSoapRequest = function (params)
... {
if(params.xmlhttp.readyState==4&¶ms.xmlhttp.status==200)...{
params.result=SOAP_SUCCESS;//未完...
params.setToken();//设置全局变量:_soap_header_m_token_
}
if(params.async&¶ms.callback)
params.callback(params.result,params);
if(!params.async)
returnparams.result;
}
// private:utils
SOAPClient._getElementsByTagName = function (document,tagName,ns)
... {
try...{
//tryingtogetnodeomittinganynamespaces(latestversionsofMSXML.XMLDocument)
varlst=document.selectNodes(".//*[local-name()=""+tagName+""]");
if(lst.length==0)
throw0;
returnlst;
}
catch(ex)...{}
//oldXMLparsersupport
if(ns+""=="undefined")
returndocument.getElementsByTagName(tagName);
returndocument.getElementsByTagName(ns+":"+tagName);
}
SOAPClient._getService = function (wsdl)
... {
varsoap_address=SOAPClient._getElementsByTagName(wsdl.documentElement,"address","soap").item(0);
returnSOAPClient._getAttribValue(soap_address,"location");
}
SOAPClient._getAttribValue = function (node,name)
... {
return(node.attributes[name]+""=="undefined")?node.attributes.getNamedItem(name).nodeValue:node.attributes[name].value;
}
// private:xmlhttpfactory
SOAPClient._getXmlHttp = function ()
... {
try...{
if(window.XMLHttpRequest)...{
varreq=newXMLHttpRequest();
//someversionsofMozdonotsupportthereadyStatepropertyandtheonreadystateeventsowepatchit!
if(req.readyState==null)
...{
req.readyState=1;
req.addEventListener("load",
function()
...{
req.readyState=4;
if(typeofreq.onreadystatechange=="function")
req.onreadystatechange();
},
false);
}
returnreq;
}
elseif(window.ActiveXObject)...{
returnnewActiveXObject(SOAPClient._getXmlHttpProgID());
}
}
catch(ex)...{}
thrownewError("YourbrowserdoesnotsupportXmlHttpobjects");
}
SOAPClient._getXmlHttpProgID = function ()
... {
if(SOAPClient._getXmlHttpProgID.progid)
returnSOAPClient._getXmlHttpProgID.progid;
varprogids=["Msxml2.XMLHTTP.5.0","Msxml2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
varo;
for(vari=0;i<progids.length;i++)
...{
try
...{
o=newActiveXObject(progids[i]);
returnSOAPClient._getXmlHttpProgID.progid=progids[i];
}
catch(ex)...{};
}
thrownewError("CouldnotfindaninstalledXMLparser");
}
假设ATL XML WebServices实现方法如下:
[id(
1
),helpstring(
"
登入系统,获得用户令牌和全图URL,以后任何方法调用必须给出令牌
"
)]
HRESULTlogin([ in ]BSTRUsername,[ in ]BSTRPassword);
id( 2 ),helpstring( " 刷新地图,取地图imgURL " )]
HRESULTrefresh([out]DOUBLE * Scale,[out,retval]BSTR * imgURL);
HRESULTlogin([ in ]BSTRUsername,[ in ]BSTRPassword);
id( 2 ),helpstring( " 刷新地图,取地图imgURL " )]
HRESULTrefresh([out]DOUBLE * Scale,[out,retval]BSTR * imgURL);
客户端IE中调用如下:
<
HTML
>
< HEAD >
< TITLE > WebGisDemoPage - WebGisAJAXClient </ TITLE >
< scriptlanguage = " javascript " src = " ajax/soapclient.js " ></ script >
< scriptlanguage = " javascript " >
// WebServiceURL
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()
... {
//同步调用,获得令牌
varsoap=newSOAPParams("登录",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
varsoap=newSOAPParams("刷新",g_url,"refresh");
SOAPClient.invoke(soap);
}
</ script >
</ HEAD >
< BODYonload = " Login(); " >
< divid = " divMap " >< imgid = " imgMap " ></ div >
</ BODY >
</ HTML >
< HEAD >
< TITLE > WebGisDemoPage - WebGisAJAXClient </ TITLE >
< scriptlanguage = " javascript " src = " ajax/soapclient.js " ></ script >
< scriptlanguage = " javascript " >
// WebServiceURL
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()
... {
//同步调用,获得令牌
varsoap=newSOAPParams("登录",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
varsoap=newSOAPParams("刷新",g_url,"refresh");
SOAPClient.invoke(soap);
}
</ script >
</ HEAD >
< BODYonload = " Login(); " >
< divid = " divMap " >< imgid = " imgMap " ></ div >
</ BODY >
</ HTML >
使用soapclient.js需要注意,我假设XML WebServices必须存在如上面所示的login方法,用于验证用户,而且m_token必须是soap头。login原型如下:
[soap_method]
[soap_header(value = " m_token " ,out = true )]
HRESULTlogin( /**/ /*[in]*/ BSTRUsername, /**/ /*[in]*/ BSTRPassword)
... {
CHARszID[MAX_TOKEN_LEN+1];
*szID=0;
DWORDdwSize=MAX_TOKEN_LEN;
HRESULThr=m_spSessionSvc->CreateNewSession(szID,&dwSize,&m_spSession);
CHECK_FAILED(hr);
szID[dwSize]=0;
m_token=CComBSTR(szID).Detach();
returnhr;
}
[soap_header(value = " m_token " ,out = true )]
HRESULTlogin( /**/ /*[in]*/ BSTRUsername, /**/ /*[in]*/ BSTRPassword)
... {
CHARszID[MAX_TOKEN_LEN+1];
*szID=0;
DWORDdwSize=MAX_TOKEN_LEN;
HRESULThr=m_spSessionSvc->CreateNewSession(szID,&dwSize,&m_spSession);
CHECK_FAILED(hr);
szID[dwSize]=0;
m_token=CComBSTR(szID).Detach();
returnhr;
}
这样,用户就可以通过soapclient.js在IE中直接调用ATL Server写的XML WebServices了。
(本文写于2006年9月,cheungmine,上海新区时空信息技术有限公司)