科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件一个调用ATL Server WebServices 的AJAX客户端

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

使用ATL Server编写的WebServices,在客户端(IE)中使用JavaScript调用服务端方法,这就是AJAX,本文提供了一个JavaScript框架soapclient.js。思想来自于http://www.guru4.net/,我根据自己的需要彻底重写了它。该soapclient.js可以作为基本的AJAX底层,提供类似C/S的调用方式。此技术可以用来实现Webgis。实际上我们也是这么做的。系统必须:MSXML3

作者:cheungmine 来源:CSDN 2008年3月28日

关键字: WebServices ATL 调用 Web开发 软件

  • 评论
  • 分享微博
  • 分享邮件

请将下面的代码完整复制到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了。

 

 

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章