Click here to Skip to main content
15,881,092 members
Articles / Web Development / IIS
Article

Invoking WebServices using JavaScript

Rate me:
Please Sign up or sign in to vote.
2.45/5 (5 votes)
12 Feb 2008CPOL8 min read 163.2K   2.5K   44   11
In this tutorial I am going to show how to invoke web services, how to write to file and how to run file using JavaScript.

Done by: Duaa Al-ansari - Jordan.

callWebServiceUsingJavaScript

Introduction

JavaScript is the most popular scripting language on the internet, and works in all major browsers, such as Internet Explorer, Mozilla, Firefox, Netscape, and Opera.

JavaScript is used in millions of Web pages to add functionality, validate forms, detect browsers, and much more.

And with the age of Web Services, come the need to call web services using JavaScript.

In this tutorial I’m going to explain the following:

·         How to use JavaScript to invoke web services APIs.

·         How to use JavaScript to write to a file.

·         How to use JavaScript to run application.

BackgroundIn this tutorial I will call one of Extentrix Web Services 2.0 – Application Edition that hosted to be used by developers for testing issues. That web service API is “launchApplication”. This web service takes the name of the application to opened from Citrix Presentation Server (which will be the Acrobat Reader in this example) and returns the content of ICA file.

I will write the result ICA file content to a file using JavaScript and then run that file using JavaScript also.

(For more information about Extentrix web services 2.0 – Application Edition visit http://www.extentrix.com/Web%20Services/Index.htm ).

Requirements

  1. Any web browser.
  2. Basic knowledge in HTML.
  3. Security Requirements:

Enable Initialize and script ActiveX controls option. For Internet Explorer, do the following:

 

A) From Internet Explorer, go to Tools >> Internet Options.

callWebServiceUsingJavaScript

Figure 1

B) Select Security tab, go to Custom level.

image003.jpg

Figure 2

C) Enable "Initialize and script ActiveX controls not marked as safe for scripting" option and click OK.

image004.png

Figure 3

Using the code

The WebService behavior is a simple, lightweight component that encapsulates the capability to invoke remote methods using the Simple Object Access Protocol (SOAP). This behavior enables Microsoft Internet Explorer 5 and later to communicate directly with Microsoft .NET WebServices and other platforms, applications, and servers that support Web Service Description Language (WSDL) 1.1.

Using the WebService behavior, browser scripts can access data from Web Services directly and use the information to update Web pages dynamically with DHTML. This new capability significantly improves the browsing experience and is faster and more efficient than the traditional approach, which requires a full refresh of the Web page.

The WebService behavior supports a wide variety of data types including: intrinsic SOAP data types, arrays, objects, arrays of objects and Extensible Markup Language (XML) data.

   There are two main files: 

     1. JavaScript_Sample.htm:

This page is the main page in this sample; it contains a link to lunch Acrobat Reader Application. It connects to Extentrix web services using JavaScript to lunch the Acrobat Reader published application on Citrix presentation server using ICA client.

2. webservice.htc:

It is an HTML Components (HTC) file that encapsulates the web service behavior. It should be enabled in order to be able to connect with the web service. You can download it from this link: http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/samples/internet/behaviors/library/webservice/default.asp.

  1. How to use JavaScript to invoke web services APIs:

    A. Create hyper link html object:

 I’ll attach the hyper link “ViewLink” with a webservice behavior.

To use the "WebService" behavior, you must attach it to an html element using the STYLE attribute, as follows:

// Create hyper link html object
<a id="ViewLink"   href="http://"  onclick="CallAPI()"  style="behavior:url(webservice.htc);"
onresult="onmyresult();"> <font color=maroon>Acrobat Reader</font></a>

webservice.htc should be in the same working directory folder.

When you click on this link it calls CallAPI() function ( onclick="CallAPI()" ) that invokes the required API. Its result will be received through onmyresult() function ( onresult="onmyresult();" ) that writes the resultant ICA file and run it to lunch the Acrobat Reader application.

    B. Create web service connection:

      Through this function you can use the previous link to create a connection to Extentrix web services.

I get the hyper link “ViewLink” created in the previous step using getElementById("ViewLink") function.

Then I set the web service description language (WSDL) URL for the web service behavior attached to “ViewLink” hyper link. And set a friendly name “Service1" for a Web service using the useService method.

useService method enables us to establish a friendly name for a Web Service URL connection that can be referenced from script instead of the long URL.

And in this method we define the web service URL that will be contact when the hyper link "ViewLink" event occurs.

I put the calling to the useService method inside init() method which will be called at the load time (in the onload event handler), you can place it in the onload event handler directly. The main idea is to be sure that this method is called before the web service behavior event attached to the hyper link “ViewLink” occurs.

For more information about useService method http://msdn2.microsoft.com/en-us/library/ms531063(VS.85).aspx

 

// creating init() function that calls the webservice:  
function init()
{
service = document.getElementById("ViewLink");
service.useService("http://www.extentrix.com/webservices/2.0.0/ExtentrixWebServicesForCPS.
asmx?WSDL","Service1");
}
// where service is the enabling link in the previous step.

    C. Calling init() function at page load:

     init() function will be called at page load.

// calling init() function at page load: 
<BODY  onload=init();>

    D. Define my credentials class:

This class is especially for Extentrix Web Service 2.0 – Application Edition. Not for any general web service. Because it is one of "LaunchApplication" API parameters.   

When you click the hyper link "ViewLink", its event will call "LaunchApplication" API that needs an instance of your credentials class as parameter.

Credentials class consists of your username, password, domain, domain type and the password encryption method. This information is specific for Citrix Presentation Server that has the acrobat reader published application.

We defined class in java script by defining a constructor method. And that will be understood as a class definition.

// Define my credentials class:
function Credentials(UserName,Password,Domain,Type,Method)
{
this.UserName=UserName;
this.Password=Password;
this.Domain=Domain;
this.DomainType=Type;
this.PasswordEncryptionMethod=Method;
}

    E. Invoke launchApplication API:

CallAPI(): this function will be called when "onclick" event for the "ViewLink" hyper link object occurs (when the hyper link is clicked).

This function creates your credentials object, and set its members. The credentials are set to Extentrix test drive published web services.

Then it invokes launchApplication API that takes these parameters: Application name, credentials, client name and client IP.    

In the client name use your machine name, and for the client IP set the IP for your machine.

Calling "launchApplication" API is done using "callService" function that takes these parameters: API name and its parameters.

The callService() method initiates the engagement of the WebService behavior with the Web service. Here is its syntax:

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

Where:

·   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.

·   sFriendlyName is the friendly name associated with the Web service. Call the useService() method to assign a friendly name to your Web service.

·   oCallHandler is the callback handler function for processing the result object. This parameter is optional.

·   funcOrObj is one of the following possible values.                     

  strFuncName: A string representing the name of the remote function being called. It must be bounded by single or double quotation marks.          

  objCall: A call object, which has the necessary properties defined to call a remote function. This parameter is required.

·   oParam are a comma-delimited list of parameters that the Web service's API expects. This parameter is required.

 

// Calling the API:   
function CallAPI()
{
var myusername = "citrixdesktop";
var mypassword = "demo";
var mydomain = "testdrive";
var mytype = 0;
var mymethod = 0;
var credentials = new Credentials(myusername,mypassword,mydomain,mytype,mymethod);
try
{
iCallID = service.Service1.callService("LaunchApplication", "PDFViewer",
credentials ,"w2k3-s3","172.19.8.103");
}
catch(e)
{
alert(e.message);
}
}

  2. How to use JavaScript to write to a file:

Now we can receive API results using "onresult" property in the enabling link that calls "onmyresult" function.   

The onresult event fires when a result has been received from a remote Web service using the WebService behavior. It is only available to objects in the document to which the WebService behavior is attached.

The event object for onresult event is generally available in the Result object. This contains the following properties:

·   result.id: Returns a unique identifier that is associated with a particular instance of the callService() method call.

·   result.value: Returns the value, or values, of the method call. The data type returned depends on the definition of the method in the service description.

·   result.raw: Returns the whole XML data received from the server, including the packet headers and envelopes when SOAP is used.

·   result.error: Returns a Boolean, specifying if there has been an error. If true, the method call resulted in an error; if false, the method was called successfully.

   When result.error is true and iCallID equals event.result.id, an error occurred. Hence the errorDetail object will be available as a property of the result object:

·   result.errorDetail.code :A cryptic error code. Can be VersionMismatch, MustUnderstand, Client, or Server.

·   result.errorDetail.string: A more descriptive error message. For example: "Error is Invalid argument."

·   result.errorDetail.raw: The entire XML data packet, received from the server.                                                                                                 

Otherwise, if API calling is done successfully, onmyresult() function will receive the resultant ICA file content using event.result.value and write it into a file on the client’s machine using Scripting.FileSystemObject.

There are three steps for writing a file and saving it in javascript:

·   Create a new Scripting.FileSystemObject object through ActiveX. Scripting.FileSystemObject is a COM object which can be fully exploited through ActiveX Script Tasks tto be used in writing a file.

·   Use the OpenTextFile method of the FileSystemObject object with the ForWriting flag set as true

  OpenTextFile is a function that takes three parameters:
Path of the file to be written (required).
Iomode argument that decide file action (Use 2 for writing).
Create argument can be either True, which will create the specified file if it does not exist, or False, which won't.

·   Write the data and close the file.

  The code looks like this example:

// Catch the result of calling the API:    
function onmyresult()
{
if ((event.result.error)&&(iCallID==event.result.id))
{
var xfaultcode = event.result.errorDetail.code;
var xfaultstring = event.result.errorDetail.string;
var xfaultsoap = event.result.errorDetail.raw;
alert("Error");
}
Else
{
var icaContent = event.result.value;
array = icaContent.split('\n');
var fileName = "c:/content.ica";
var Fs = new ActiveXObject("Scripting.FileSystemObject");
var Output = Fs.OpenTextFile(fileName,2,true);
var content = array[0] + "\n";
for (i = 1; i < array.length; i++)
{
content += array[i] + "\n";
}

Output.write(content);
Output.close();

3. How to use JavaScript to run application:

      Finally we can run it using ICA client using "WScript.Shell". To run ICA file: 

      Set the file URL.     
      Create an ActiveXObject assigned to the WScript.Shell object.
    
      Use run function that take file url as a parameter.

url = "file:///"+ fileName;
WSH = new ActiveXObject("WScript.Shell");
WSH.run(url);
}
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Extentrix Systems
Jordan Jordan
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 1 Pin
Antony M Kancidrowski13-Jan-10 5:23
Antony M Kancidrowski13-Jan-10 5:23 
Generalreg: can we make result object programatically Pin
Vanamaindia9-Aug-09 21:07
Vanamaindia9-Aug-09 21:07 
GeneralUnable to execute Pin
Aman Bhullar21-Apr-09 19:49
Aman Bhullar21-Apr-09 19:49 
QuestionJSON Pin
dm.9912-Jan-09 7:43
dm.9912-Jan-09 7:43 
GeneralDesktop Service using javascript. Pin
manjeetbhadwal11-Dec-08 22:53
manjeetbhadwal11-Dec-08 22:53 
Generaljavascript and webservice Pin
lakshmikris9-Oct-08 20:48
lakshmikris9-Oct-08 20:48 
GeneralCalling web services with javascript. Pin
AdamNThompson18-Feb-08 11:32
AdamNThompson18-Feb-08 11:32 
The thing is that most users on the web are going to have default security settings on their browser. I however like to call web services using Javascript as well. How I get arroud this problem is to build a webservice that call the web service that I want to use. This way my httprequest are going to the same url, and thus are not subject to being stoped bu browser security settings. Plus, I like to do the majority of my work on the server side, so I may have my web service return something a little easyer to work with that fits my needs. For example I may choose to return a string containg a bunch of html that I plan to throw right on to the page.

Anyway, here is a short but sweet example of how I make the call.

<br />
<br />
function SendToAFriend() {<br />
<br />
// Create XmlHttprequestObject<br />
var xmlhttp;<br />
if (window.XMLHttpRequest) {<br />
  xmlhttp = new XMLHttpRequest();<br />
}<br />
else if (window.ActiveXObject) {<br />
  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");<br />
}<br />
<br />
// Get values from text boxes<br />
var name = document.getElementById('txtYourName').value;<br />
var email = document.getElementById('txtEmail').value;<br />
var message = document.getElementById('txtMessage').value;<br />
<br />
//alert(name);  //Debug<br />
//alert(email);  //Debug<br />
//alert(message);  //Debug<br />
<br />
// Build SOAP request<br />
xmlhttp.open("POST", "MOOMerWS.asmx", false); <br />
xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");<br />
xmlhttp.setRequestHeader("SOAPAction", "http://tempuri.org/SendToAFriend"); <br />
xmlhttp.send("<?xml version='1.0' encoding='utf-8'?>"+"\n\n"+"<soap:Envelope"+ <br />
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'+ <br />
' xmlns:xsd="http://www.w3.org/2001/XMLSchema"'+ <br />
' xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'+<br />
' <soap:Body>'+<br />
' <SendToAFriend xmlns="http://tempuri.org/">'+<br />
' <name>'+ name +'</name>'+<br />
' <email>'+ email +'</email>'+<br />
' <message>'+ message +'</message>'+<br />
' </SendToAFriend>'+<br />
' </soap:Body>'+<br />
' </soap:Envelope>');<br />
<br />
// Get XML response<br />
var result = xmlhttp.responseXML.xml; <br />
<br />
//alert(result);  //Debug<br />
<br />
// Use string manipulation to pull out <br />
// the boolean response from the xml response<br />
var int1 = result.indexOf('<SendToAFriendResult>');<br />
var int2 = result.indexOf('</SendToAFriendResult>');<br />
var strSendToAFriendResult = result.substring((int1 + 21), int2); <br />
<br />
//alert(strSendToAFriendResult); //Debub<br />
<br />


I also have a sample on how to call a web servoce with VBScript here.
http://www.codeproject.com/KB/vbscript/SOAP___Classic_ASP.aspx[^]

Anyway, cool artical. Sometime it makes sence to call web services with javascript.

I am pretty stokec about the new WCF services. It's supposed to make it easyer to create RESTful web services with .NET, then you can make em' return JSON! Of corse that means we will be able to call these web services crodd domain with javascript using dynamic script tags! Maybe I'm just getting a case of the smarts, but it all seems pretty cool to me.

-Adam

-Adam N. Thompson

GeneralRe: Calling web services with javascript. Pin
Mady Gowtham8-Dec-15 20:50
Mady Gowtham8-Dec-15 20:50 
GeneralNot very useful Pin
Dewey13-Feb-08 16:42
Dewey13-Feb-08 16:42 
GeneralRe: Not very useful Pin
p.valenta17-Feb-08 14:46
p.valenta17-Feb-08 14:46 
GeneralRe: Not very useful Pin
Matthias Hertel18-Feb-08 19:48
professionalMatthias Hertel18-Feb-08 19:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.