架构人生

如何用JavaScript调用Web服务——callService/useService

Web服务在分布式架构中起着重要的角色,在学习Web服务中,对Web Service的一些调用服务的方法做了一些整理。今天主要讲通过JavaScript中的两个方法——useService和callService来调用一个已存在的Web服务。

首先,看一下callService这个方法的语法:

iCallID = sElementID.sFriendlyName.callService([oCallHandler], funcOrObj, oParam);

iCallID是调用服务后返回的ID。

sElementID是useService方法的一个控件元素ID。稍后讲如何用userServie。

sFriendlyName是服务名,比如.NET中Default.asmx,则这里是Default。

oCallHandler是处理响应结果的回调函数,因为有些请求无需关注响应结果,在这里是可选参数。

funcOrObj是web服务中的方法,在.NET中便是标有[WebMethod]的一些公用方法。

oParam是Web Method中的参数,可以是0,1,2,…个参数。

以下是做的一个例子:

        //请求登陆
        function loginRequest() {
            
//服务Default.asmx, 方法CheckLoginByIO
            iCallID = service.Default.callService(loginResponse, "CheckLoginByIO", userid.value, userpwd.value, "127.0.0.1");
        }

        
//响应登陆
        function loginResponse(res) {
            
//调用服务出错
            if (res.error) {
                loginError.innerText 
= res.errorDetail.string;
            }
            
else if (res.value.IsError) {//服务后来业务出错
                loginError.innerText = res.value.ErrorMessage;
            }
            
else if (res.value.IsLogin) {//登陆成功
                loginError.innerText = "login successfully,and your name is " + res.value.UserName;
            }
            
else {//登陆失败
                loginError.innerText = "login failed, username or password is incorrect.";
            }
        }

注意,如果你想知道res.value里有哪些参数,而又不知道业务逻辑那边到底返回了什么参数给你,你直接用Visual Studio 2008可以调试,不要忘了,JavaScript在IDE里的断点调试功能也是无比强大的,不逊于C#.

鉴于对useService的用法,下面顺便讲一下createCallOptions:

        //===================================另一种风格请求Web服务================================//
        //请求执行SQL语句方法
        function executeSQLRequest() {
            
var co = serviceZivsoft.createCallOptions(); //createCallOptions
            co.funcName = "ExecuteSql";//web服务方法名
            iCallID = serviceZivsoft.Default.callService(executeSQLResponse,co,sql.value);
        }

        
//响应执行SQL语句方法
        function executeSQLResponse(res) {
            
if (res.error) {
                Span1.innerText 
= res.errorDetail.string;
            }
            
else {
                
//返回数据库表记录影响条数
                Span1.innerText = res.value;
            }
        }

 

其次,看一下useService如何使用。

useService刚开始让我费解的是哪里来的这个方法,后来发现我们需要去微软官方上下载一个叫webservice.htc的文件。

下载完这个文件,将其放到根目录下,在你的html里写上这样一段代码就轻松搞定:

<body onload="init()" id="serviceZivsoft" style="behavior: url(webservice.htc)"/>

 

其实,这是我个人风格,我喜欢在onload时初始化web服务,初始化代码如下:

        var iCallID;
        
//=====================================
        //       初始化对Web服务的调用
        //      Autor: Lihua
        //      Url: http://www.zivsoft.com
        //=====================================
        function init() {
            
//由于我的Web服务在同一个项目,所以用了相对目录
            serviceZivsoft.useService("Default.asmx?WSDL""Default");
        }

 

关于useService更详细的解释,可以去MSDN上查阅,用法还是比较简单的。

 

最后,给一个完整的HTML如下:

<html>
<head>
    
<title>采用userSErvice调用.NET Web Services</title>

    
<script language="JavaScript" type="text/javascript">
        
var iCallID;
        
//=====================================
        //       初始化对Web服务的调用
        //      Autor: Lihua
        //      Url: http://www.zivsoft.com
        //=====================================
        function init() {
            
//由于我的Web服务在同一个项目,所以用了相对目录
            serviceZivsoft.useService("Default.asmx?WSDL""Default");
        }

        
function Add() {
            
//iCallID = sElementID.sFriendlyName.callService([oCallHandler], funcOrObj, oParam);


            
//iCallID: is the returned ID of the service call. 
            //In case of asynchronous call, this ID should be matched with the ID returned as a property of the result object. 
            //Only when matched can the result object be associated with this service call.
            iCallID = serviceZivsoft.Default.callService(mathResults, "Add", a.value, b.value);
        }

        
function mathResults(result) {
            
// if there is an error, and the call came from the call() in init()
            if (result.error) {
                
// Pull the error information from the event.result.errorDetail properties
                var xfaultcode = result.errorDetail.code;
                
var xfaultstring = result.errorDetail.string;
                
var xfaultsoap = result.errorDetail.raw;
                
// Add code to handle specific error codes here
                lblError.innerHTML = "ERROR. Method call failed!"
                
+ "<br/>iCallID:" + iCallID
                
+ "<br/>Fault Code: " + xfaultcode
                
+ "<br/>Fault String:" + xfaultstring
                
+ "<br/>SOAP Data:" + xfaultsoap
                
+ "<br/>Result:" + result.value;
            }
            
// if there was no error
            else {
                
// Show the arithmetic
                c.value = result.value;
            }
        }

        
//请求登陆
        //--------------ZIVSOFT.COM---------------
        //--------------Lihua Zhou----------------
        function loginRequest() {
            
//服务Default.asmx, 方法CheckLoginByIO
            iCallID = serviceZivsoft.Default.callService(loginResponse, "CheckLoginByIO", userid.value, userpwd.value, "127.0.0.1");
        }

        
//响应登陆
        //--------------ZIVSOFT.COM---------------
        //--------------Lihua Zhou----------------
        function loginResponse(res) {
            
//调用服务出错
            if (res.error) {
                loginError.innerText 
= res.errorDetail.string;
            }
            
else if (res.value.IsError) {//服务后来业务出错
                loginError.innerText = res.value.ErrorMessage;
            }
            
else if (res.value.IsLogin) {//登陆成功
                loginError.innerText = "login successfully,and your name is " + res.value.UserName;
            }
            
else {//登陆失败
                loginError.innerText = "login failed, username or password is incorrect.";
            }
        }

    
</script>

</head>
<body onload="init()" id="serviceZivsoft" style="behavior: url(webservice.htc)">
    
<input id="a" value="2" />+
    
<input id="b" value="3" />=
    
<input id="c" />
    
<input type="button" value="compute" onclick="Add();" />
    
<p>
        
<span id="lblError"></span>
    
</p>
    
<hr />
    
<input id="userid" />
    
<input id="userpwd" type="password" />
    
<input type="button" value="login" onclick="loginRequest();" />
    
<p>
        
<span id="loginError"></span>
    
</p>
</body>
</html>

 

补充讲一下用Post方法调用.NET Web Services,调用方式如下:

<html xmlns="http://www.w3.org/1999/xhtml">
      <body>
          
<form action="http://172.25.142.27/default.asmx/Add" method="post">
                
<input name="x" />
                
<input name="y" />
                
<input type="submit" value="Enter" />
          
</form>
      </body>
</html>

 

另外,用心的朋友会注意到,默认情况下,.NET Web Services在远程机器不能使用POST来调用远程WEB服务,除非在WEB服务配置web.config中设置:

<system.web>
      <webServices>
             <protocols>
                  <add name="HttpGet"/> 
                  <add name="HttpPost"/> 
            </protocols> 
      </webServices>
</system.web>

如果没有设置,你将会得到下面这个错误: The test form is only available for requests from the local machine. 

想尝试的朋友,可以用这个服务: http://www.w3schools.com/webservices/tempconvert.asmx

The following shows 倒计时.

<div id="divdown1"/>
<script language="javascript" type="text/javascript">
 
var interval = 1000;
 
function ShowCountDown(year,month,day,divname)
 {
        
var now = new Date();
        
var endDate = new Date(year, month-1, day);
        
var leftTime=now.getTime()-endDate.getTime();
        
var leftsecond = parseInt(leftTime/1000);
        var day1=Math.floor(leftsecond/(60*60*24)); 
        var hour=Math.floor((leftsecond-day1*24*60*60)/3600);
        var minute=Math.floor((leftsecond-day1*24*60*60-hour*3600)/60);
        var second=Math.floor(leftsecond-day1*24*60*60-hour*3600-minute*60);
        
var cc  =   document.getElementById(divname);
        if(hour<10){hour="0"+hour;}
        
if(minute<10){minute="0"+minute;}
        
if(second<10){second="0"+second;}  

        cc.innerHTML=""+day1+"天 "+hour+""+minute+""+second+"";
 }
 window.setInterval(
function(){ShowCountDown(1982,10,20,'divdown1');}, interval);
</script>

本文链接:http://www.cnblogs.com/architect/archive/2009/05/14/1456818.html
关于作者:http://www.zivsoft.com/

 

posted on 2009-05-14 14:41 周利华 阅读(...) 评论(...) 编辑 收藏

导航

公告