How to Develop an AJAX App Using a Proxy

The following article walks you through developing an AJAX app
using a proxy server. The sample code will then:

  • Retrieve a list of CUCM servers
  • Retrieve a list of devices that the owner manages
  • Modify a device's description

Because of its REST interface, UDS can be accessed in a number of ways. Applications written in Java, C#, and Objective-C can use a network stack to access UDS resources directly. AJAX-based applications can also be used, but there are restrictions. Currently UDS does not support the headers that implement Cross-Origin Resource Sharing (CORS). That is, due to modern browser security policy, AJAX code executing within the browser cannot directly access UDS resources, unless the system is in the same domain as the UDS server.

However, there is an established work-around to make browser access possible from other domains. The AJAX code must execute as a Web page on a proxy server. The sample program provided here consists of AJAX code that displays and then manages a UDS device resource. It requires that you to set up a proxy server to execute the application, and the process is explained here.

Before You begin

To complete this exercise, you need the following tools.

  • Access to CUCM server
  • The username and password for an end user on the CUCM server
  • A modern Web browser (IE9, Firefox 21, or Chrome)
  • The nginx server software at (http://wiki.nginx.org/Install)
  • The downloaded sample app that contains the server configuration file and the UDS sample application.

Download and Install the Nginx Proxy Server

Go to http://wiki.nginx.org/Install and download and nginx.

Nginx is a light-weight, high-performance, open source HTTP server. (Note that other freely available HTTP server software--such as the SimpleHTTPServer bundled with the Python programming language--can be used.)

An executable binary version of nginx for Windows is used here. The zip file containing the software was downloaded and expanded to produce a folder named nginx-1.5.0. Examining this folder's contents with Windows Explorer, you can see that there are several sub-folders. One of these folders contains files that handle the server configuration (conf) and the other folder holds HTML content (html). There is also the executable binary, nginx.exe, which is the server itself.

Open a Command window. Change directory (cd) to the nginx-1.5.0 directory. To confirm that nginx works, type the following into the Command window:

Start nginx and confirm it is running

1
2
start nginx
tasklist /fi "imagename eq nginx.exe"

You should see two tasks associated with nginx.exe. Also, you can point your browser to http://localhost/ and a nginx welcome browser page should appear.



Now stop the server by typing: Stop nginx
1
nginx -s stop

The server has to be stopped to ensure that the changes made to ths server's configuration and start page take effect.



Modify the Server Configuration File

Note that the nginx.conf file within the config folder handles the nginx server configuration. For this example, change the server section so that localhost listens on port 8002 instead of 80. (Port 80 and 8000 are already taken by other programs so I changed the port number to 8002 so that I won't have any conflicts) In addition, add the proxy directory and HTTP headers to redirect to https://{cucm-ip-address}/cucm-uds. Remeber to replace {cucm-ip-address} with your actual CUCM's IP Address. See changes in red:



Update nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen <span style="color:#ff0000;">8002</span>;
server_name localhost;
.
.
.
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
<span style="color:#ff0000;">location /cucm-uds {
proxy_pass https://{cucm-ip-address}/cucm-uds;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}</span>
.
.
.
}


Establish connection to CUCM, and then launch nginx. Use the tasklist command to verify that nginx started. Note: if you do not set up a connection to the UDS server, the nginx server will abort, as its new configuration requires access to the UDS server.

Add the AJAX code to the Web start page

If nginx started successfully, then all that is left to do is add your AJAX application as the server's start page.

In the Command window, stop the nginx server. Next, change directory to the html directory and rename the index.html file there to something different. Now copy the example index.html file (which contains the sample application's AJAX code) into the html folder. Start nginx.

Now point the browser to http://localhost:8002/. A Web page with four buttons should appear. This is the sample application's UI.

Description of the Sample UDS Application

The first button is for making a servers resource request to locate a CUCM server. The button labelled Request Servers makes the HTTP request to the UDS server. The button invokes the function requestServers(). The essence of the requestServers() code is:



Example Request
1
2
3
4
5
6
7
8
9
http_request.open('GET', getStr, true);
http_request.onreadystatechange = function() { generate_serverTable(); };
http_request.setRequestHeader("Accept", "application/xml");
var credentials = btoa(user + ":" + password);
http_request.setRequestHeader("Authorization", "Basic " + credentials);
http_request.send(null);


The variable getStr is actually made from an uri argument passed to the function, but for clarity the actual URL is shown here. The code handles the authorization header and assigns the function generate_serverTable() to process the response to the HTTP GET request when it completes. Generate_serverTable() dynamically builds a list of CUCM server names by parsing the XML of the response body. It uses Javascript's getElementsByTagName() function to extract all elements from the response tagged as "server". The table is built dynamically because the site might host more than one UDS server.

The next button makes a UDS devices resource request to the server. It is labeled Request Devices, and handles a remote HTTP request. The button invokes the function makeRequest(). The URL passed to the function is:

Request URL for all of the user's devices
1
getStr = "http://localhost:8002/cucm-uds/user/"+user+"/devices";


This is the devices resource request. The variable user can be edited to supply the user name, while password provides the password. Other than the URL, the code that performs the HTTP GET method here is identical to that used for the servers resource request. Note that both requestServers() and makeRequest() have code that checks of the presence of a XMLHttpRequest object, and if it is absent, it invokes XMLHttpRequest to manage the HTTP connection. This is done since users might click the Devices request button before clicking on the Servers request button.



The makeRequest() function designates generate_displayTable() to parse the XML response body returned by the devices resource request. Generate_displayTable() uses Javascript createElement() calls to assemble a table's header, body, and then rows as it parses the XML. As with the servers table, since the number of devices cannot be anticipated, the devices table is assembled dynamically. The table display code uses getElementsByTagName() to extract the specified elements out of the XML, such as the device's ID, name, model, type and description. The device ID and description are also saved in variables to make a device resource request.

Using the example program

To have the program request a CUCM server and the owner's device list from CUCM, first edit the user and password vars to that of the owner's name and password. Certain UDS resources require authorization to access, so credentials must be provided. Conversely, comment out the statement that generates the HTTP Authorization header. Without the Authorization header, the browser will display a login dialog that prompts the user for this information.



Next edit and provide the strings url, sendURL, and serverURL to contain the paths to the UDS resources for servers, devices, and device, respectively. Restart nginx and go to the proxy server's home page by typing http://localhost:8002/ into the address bar of a browser.



Click on the Request Servers button and a table of UDS servers on the site should appear. Now click on the Request Device button. This sends a UDS devices request to the server with the user's credentials. If everything is set up properly, a black-and-white table appears that summarizes the characteristics for every device that the user owns.

Beneath this should be a short, two-row table with a title of Change Device Description. It displays a device index value and the description string for the device at that index. Note that the index value was generated as part of the table display; it does not correspond to any device resource information. Behind the scenes, the application saves the device's ID for use when a device selection is made. Since you can only change one device at a time, the Change Device Description table is made of static HTML.

To change the current device's description, click in the cell adjacent to Device Description. The current string disappears and you can enter a new text string. The interaction is implemented by Javascript onclick() and onchange() functions attached to the table cells for the device ID and Description table entries.

Click the Send Change Request button beneath this table to send the request. The code uses the index number to obtain the device's ID and then formats a device resource URL with it. The device resource URL address is:

Request URL for the user's device
?
1
2
var deviceURL = "http://localhost:8002/cucm-uds/user/"+user+"/device/" + devicePkIds[currentIndex];


Where the array devicePkIds holds the device IDs extracted from the response and currentIndex is the index number for the device's position in the table and in the array.



This time the code uses the XMLHttpRequest object and a PUT method to send a request body to the server. The var requestBody holds the actual XML payload that specifies the device description element, along with the contents you entered into Description cell of the Change Device Description table. The code that does this is simply:

Request Body
1
2
3
4
5
6
var requestBody = "<device>" +
"<description>" +
currentDeviceDescript +
"</description>" +
"</device>\r\n";


Where the variable currentDeviceDescript holds the new description obtained from the Change Description cell of the table. Unlike the previous HTTP transactions that used the GET method, the PUT transaction uses the XMLHttpRequest send method to transmit the XML payload in requestBody to the UDS server.

For more information on the devices and device resource, see the UDS API Reference.

After a brief interval the UDS returns a response that causes an alert to appear. The alert states whether the update request was successful or not.

To specifiy a different device, click on the cell adjacent to the Device Index. The index number disappears, and the index number for another device in the table can be entered. After typing in a new number, click outside of the index number field and the contents of the Device Description cell should change to the description of the device at the specified index. Click the Send Change Request button to modify the description.

Troubleshooting

Most Ajax problems with the UDS can be sorted out by the HTTP status code that is sent in response to a request.

  • 401 -- Unauthorized. Something is wrong with the user credentials. Either the name or password was entered incorrectly.
  • 404 -- Not Found. Check that URL being used to make the UDS request is correct and exists.
  • 415 -- Unsupported Media Type. The user credentials are valid but something is wrong with the request body for a POST or PUT method. Check that the HTTP headers specify a Content-Type of application/xml. Also, check that the request body's XML payload is being formatted correctly.

If you come across a pop-up that says "Problem with device read", this means that you are not using the proxy to test the sample app. To use the proxy, type in http://localhost:8002/index.html into your browser address bar.

If your browser says it is unable to establish a connection to the server as localhost:8002, you need to start nginx. Simply open up the command window, cd to the nginx directory, and then type in start nginx.

For additional response code details, please visit Response Codes in the API Reference Guide.

Visit the UDS Developer Forums to ask questions and interact with other developers.