Done by: Duaa Al-ansari - Jordan.
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
- Any web browser.
- Basic knowledge in HTML.
- Security Requirements:
Enable Initialize and script ActiveX controls option.
For Internet Explorer, do the following:
A)
From Internet Explorer, go to Tools >>
Internet Options.
Figure 1
B) Select Security tab, go to
Custom level.
Figure 2
C) Enable "Initialize and script ActiveX
controls not marked as safe for scripting" option and click OK.
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:
<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
function init()
{
service = document.getElementById("ViewLink");
service.useService("http://www.extentrix.com/webservices/2.0.0/ExtentrixWebServicesForCPS.
asmx?WSDL","Service1");
}
C. Calling init() function at
page load:
init()
function will be called 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.
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.
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:
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);
}
}