Ajax is a technology that enables a javascript program (embedded in a web page displayed by your browser) to communicate with a server and provide dynamic content. This communication occurs “under the covers” and is, hopefully, “seamless.” The masher’s getWebServiceResult uses Ajax to retrieve information from a commercial Web service.
function getWebServiceResult() { if (window.XMLHttpRequest) {// code for modern browsers request = new XMLHttpRequest(); } else {// older versions of IE request = new ActiveXObject("Microsoft.request"); } var url = "https://masher.cunyfirst.cuny.edu/proxy"; request.open("GET", url, false); // false means synchronous operation request.send(); if (request.readyState != 4 || request.status != 200) { alert("AJAX error: " + request.statusText + " (state=" + request.readyState + ", status=" + request.status + ")"); return null; } return getSelectedItem(request.responseText); }
Problem is, the masher page comes from from https://masher.cunyfirst.cuny.edu but the Web service is provided by http://outside-webservice.com. Access is prohibited by the “Same Origin Policy” which is especially restrictive for Ajax requests (though there are work-arounds). So we “proxy” these requests through the masher’s web server. getWebServiceResult connects to masher.cunyfirst.cuny.edu which relays requests for /proxy to outside-webservice.com. As far as the browser is concerned, masher.html and the proxied page are in the same domain. This approach also allows us to alter the request on its way to outside-webservice.com. To add authentication information (outside-webservice requires a user name and password), for example. And it allows a javascript routine in an SSL protected page (masher.html) to communicate with a non-SSL Web service. All this for free, no programming required, just five lines of Apache configuration:
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so RequestHeader set Authorization "Basic authstring" ProxyPass /proxy http://outside-webservice.com/ ProxyPassReverse /proxy http://outside-webservice.com/
Where authstring is base 64 encoded user:password.
The response from outside-webservice.com is an XML page that contains a collection of “items”:
<result count="3"> <item id="item0"> <select>false</select> <value>first value</select> </item> <item id="item1"> <select>true</select> <value>second value</select> </item> <item id="item2"> <select>false</select> <value>third value</select> </item> </result>
We’re only interested in one. I found a convenient XML to JSON parser that made it easy to find it.
<script type="text/javascript" src="http://www.thomasfrank.se/downloadableJS/xml2json.js"></script> function getSelectedItem(response) { var responseJson = xml2json.parser(response); var result = responseJson.result; var items = result.item; if (typeof items === 'undefined') { return null; } for (var i = 0; i < items.length; i++) { var item = items[i]; if (item.select == 'true') { return item; } } return null; }
This is sort of a “mashup” style of programming. Rather than write my own parser (limited purpose and designed for this XML document) I stole Thomas Frank’s general purpose one.
Resources
Ross turned me on to this useful article about mashups.
I wrote several of my own proxies before settling on the Apache/mod_proxy approach. I really like Jersey. My colleague Vamsi Naidu introduced me to IBM’s
RPC Adapter (and here). Then there’s always Apache’s trusty HTTP Client.
I found a few interesting articles on javascript and PeopleCode
http://community.psoftpros.net/profiles/blogs/injecting-javascript-amp-ajax
http://hosteddocs.ittoolbox.com/VRM100804.pdf
http://greysparling.com/Blog/enhancing-the-usability-of-peoplesoft-applications
http://xtrahot.chili-mango.net/2005/08/peoplesoft-page-javascript-insertion
http://peoplesofttipster.com/2007/07/24/counting-characters-in-a-field