Ahmad Masykur

Share your knowledge although one function!

About the author

Ahmad Masykur is a Software Architecture Engineer at PT. Freeport Indonesia Jakarta Indonesia.
In this blog, I share things of interest to me. Most topics are likely to be related to software development, but don't hold me to it.

Certificates



Awards


Powered by

Widget Prayer Time not found.

There is an error in XML document (4, 16278).X

Page List

Validators


Ahmad Masykur

Invoke Web Service Menggunakan XMLHttpRequest

Banyak library Ajax yang sudah gede dan banyak fiturnya seperti ASP.NET AJAX, Anthem.NET, AjaxAnywhere, ajaxCFC, AJS, Dojo, Rico dan beberapa library lainnya. Dalam tulisan ini akan saya jelaskan konsep invoke Web Service langsung menggunakan objek XMLHttpRequest (XHR). Saya asumsikan bahwa pembaca sudah memahami konsep dasar XMLHttpRequest, jika belum silakan baca tulisan saya sebelumnya di Pengenalan AJAX.

Pertama buat root object dengan nama Masykur, root object ini bisa disamakan sebagai namespace pada OOP.

if (!window.Masykur) {
    window.Masykur = {};
}

Setelah root object dibuat kemudian buat member yang berisi DOM dan Ajax. DOM digunakan untuk mendapatkan informasi DOM dan browser sedangkan Ajax adalah object yang menangani komunikasi singkron dengan Web Service.

if (!Masykur.DOM) {
    Masykur.DOM = function() {}
}
if (!Masykur.Ajax) {
    Masykur.Ajax = function() {}
}

Pada objek Masykur.DOM, tambahkan property untuk pengecekan browser. Pengecekan browser ini digunakan untuk mengecek kemampuan dari masing-masing browser karena masing-masing browser menggunakan objek yang berbeda untuk menangani XHR maupun dokumen XML.

Masykur.DOM.isInternetExplorer = (navigator.userAgent.indexOf("MSIE") >= 0);
Masykur.DOM.isMozilla = (navigator.userAgent.indexOf("Gecko") >= 0);
Masykur.DOM.isOpera = (navigator.userAgent.indexOf("Opera") >= 0);

Pada objek Masykur.Ajax, buat variabel nameSpace yang digunakan sebagai namespace pada Envelope SOAP. Selain variabel juga tambahkan fungsi set dan get namespace.

Masykur.Ajax = function() {
    var nameSpace = "http://tempuri.org/";
    this.setNameSpace = function(ns){
        nameSpace = ns;
    }//end setNameSpace()
    
    this.getNameSpace = function(){
        return nameSpace;
    }//end getNameSpace()
}

Buat objek XHR lintas browser dengan mencoba semua metode dari create XMLHttpRequest dari JavaScript object, ActiveX dan SOAPCall object. Ini dimaksudkan supaya semua library tidak tergantung dengan browser yang digunakan, dapat berjalan baik IE, Firefox maupun Opera.

Masykur.Ajax = function(){
    // ...
    var ajaxObject = function(){
        try{return new XMLHttpRequest();}catch(ex){};
        try{return new ActiveXObject("Microsoft.XMLHTTP");}catch(ex){};
        try{return new SOAPCall();}catch(ex){};
    }//end ajaxObject()
}

Buat fungsi penanganan error yang kemudian dapat di-override dengan fungsi sendiri saat digunakan.

Masykur.Ajax = function(){
    // ...
    this.onError = function(error){
        alert(error);
    }//end onError()
}

Setelah semua persiapan objek XHR selesai, sekarang tinggal buat fungsi callService untuk invoke ke Web Service.

Masykur.Ajax = function(){
    // ...
    this.callService = function(serviceUrl, soapMethod, callbackFunction /*, unlimited params */){
        // code
    }
}

Pertama yang perlu disiapkan adalah URL web service. Tambahkan "?WSDL" dibelakang URL.

if(serviceUrl.indexOf("http://") < 0)
    serviceUrl = "http://" + serviceUrl;
serviceUrl += "?WSDL";

Hal penting yang harus disiapkan adalah envelope untuk membungkus data yang akan dikirimkan ke server. Envelope berisi semua parameter yang dibutuhkan oleh web service method. Parameter dibungkus dalam tag <soap:Body>, nama parameter merupakan sebuah elemen child <soap:Body> dan valuenya dimasukkan sebagai text element parameter.

var soapEnvelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
soapEnvelope += "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
soapEnvelope += "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ";
soapEnvelope += "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
soapEnvelope += "<soap:Body>";
soapEnvelope += "<" + soapMethod + " xmlns=\"" + nameSpace + "\">";

if(arguments.length > 3){
    for (var i = 3; i < arguments.length; i++)
    {
        var params = [];
        var arg = arguments[i];
        var ieq = arg.indexOf('=');
        params[0] = arg.substr(0, ieq);
        params[1] = arg.substr(ieq + 1);
        soapEnvelope += "<" + params[0] + ">";
        soapEnvelope += params[1];
        soapEnvelope += "</" + params[0] + ">";
    }//end for
}//end if

soapEnvelope += "</" + soapMethod + ">";
soapEnvelope += "</soap:Body>";
soapEnvelope += "</soap:Envelope>";

Set event onreadystate pada objek XHR dan kembalikan hasil respon web service dalam format string setelah semua data lengkap diterima.

Terakhir buka sambungan dengan server menggunakan mode POST dan set header content-type menjadi "text/xml" dan tambahkan juga header "soapaction" dengan data namespace diikuti dengan soap method. Kirimkan soap envelope pada request body seperti pada kode berikut.

ao.open("POST", serviceUrl, true);
ao.setRequestHeader("Content-Type", "text/xml");
ao.setRequestHeader("soapaction", nameSpace + soapMethod);
ao.send(soapEnvelope);

Script lengkap dapat dilihat pada kode berikut.

if (!window.Masykur) {
    window.Masykur = {};
}
if (!Masykur.DOM) {
    Masykur.DOM = function() {}
}
if (!Masykur.Ajax) {
    Masykur.Ajax = function() {}
}
Masykur.DOM.isInternetExplorer = (navigator.userAgent.indexOf("MSIE") >= 0);
Masykur.DOM.isMozilla = (navigator.userAgent.indexOf("Gecko") >= 0);
Masykur.DOM.isOpera = (navigator.userAgent.indexOf("Opera") >= 0);

Masykur.Ajax = function(){

    var nameSpace = "http://tempuri.org/";
    
    //private method for returning an ajax enabled
    //object specific to a browser
    var ajaxObject = function(){
        try{return new XMLHttpRequest();}catch(ex){};
        try{return new ActiveXObject("Microsoft.XMLHTTP");}catch(ex){};
        try{return new SOAPCall();}catch(ex){};
    }//end ajaxObject()
    
    this.onError = function(error){
        alert(error);
    }//end onError()

    this.callService = function(serviceUrl, soapMethod, callbackFunction /*, unlimited params */){
        
        var callServiceError = this.onError;
        
        var ao = ajaxObject();
        
        if(!ao.encode){
            if(serviceUrl.indexOf("http://") < 0)
                serviceUrl = "http://" + serviceUrl;
            serviceUrl += "?WSDL";
            
            var soapEnvelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
            soapEnvelope += "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
            soapEnvelope += "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ";
            soapEnvelope += "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
            soapEnvelope += "<soap:Body>";
            soapEnvelope += "<" + soapMethod + " xmlns=\"" + nameSpace + "\">";
            
            if(arguments.length > 3){
                for (var i = 3; i < arguments.length; i++)
                {
                    var params = [];
                    var arg = arguments[i];
                    var ieq = arg.indexOf('=');
                    params[0] = arg.substr(0, ieq);
                    params[1] = arg.substr(ieq + 1);
                    soapEnvelope += "<" + params[0] + ">";
                    soapEnvelope += params[1];
                    soapEnvelope += "</" + params[0] + ">";
                }//end for
            }//end if
            
            soapEnvelope += "</" + soapMethod + ">";
            soapEnvelope += "</soap:Body>";
            soapEnvelope += "</soap:Envelope>";
            
            ao.onreadystatechange = function(){
                
                if(ao.readyState == 4){
                    
                    if(Masykur.DOM.isOpera){
                        //opera
                        var response = ao.responseXML.getElementsByTagName(soapMethod + "Result")[0];
                        if(!response)
                            response = ao.responseXML.getElementsByTagName(soapMethod + "Response")[0];
                        if(!response){
                            callServiceError("WebService does not contain a Result/Response node");
                            return;
                        }//end if
                        
                        ao.callbackFunction(ao.responseXML.getElementsByTagName(soapMethod + "Result")[0].innerHTML);
                    }
                    else if(Masykur.DOM.isInternetExplorer){
                        //IE
                        var responseXml = new ActiveXObject('Microsoft.XMLDOM');
                        responseXml.loadXML(ao.responseText);
                            
                        var responseNode = responseXml.selectSingleNode("//" + soapMethod + "Result");
                        if(!responseNode)
                            responseNode = responseXml.selectSingleNode("//" + soapMethod + "Response");
                        if(!responseNode) {
                            callServiceError("Response/Result node not found.\n\nResponse:\n" + ao.responseText);
                            return;
                        }//end if
                        var resultNode = responseNode.firstChild;
                        if (resultNode != null){
                            try{
                                callbackFunction(resultNode.xml);
                            }
                            catch(ex){
                                callServiceError(ex);
                            }//end tc
                        }
                        else{
                            try{
                                callbackFunction();
                            }
                            catch(ex){
                                callServiceError(ex);
                            }//end tc
                        }//end if
                    }
                    else if(Masykur.DOM.isMozilla){
                        //Mozilla
                        var xmlDocument = new DOMParser().parseFromString(ao.responseText, "text/xml");
                        
                        var xr = xmlDocument.evaluate("//" + soapMethod + "Result", 
                                 xmlDocument.childNodes[xmlDocument.childNodes.length-1], 
                                 null, 
                                 XPathResult.ANY_TYPE, null);
                        var responseNode = xr.iterateNext();
                        
                        if(!responseNode)
                            callServiceError("Response/Result node not found.\n\nResponse:\n" + ao.responseText);
                        
                        var resultNode = responseNode.firstChild;
                        
                        if (resultNode != null){
                            try{
                                callbackFunction(resultNode.textContent);
                            }
                            catch(ex){
                                callServiceError(ex);
                            }//end tc
                        }
                        else{
                            try{
                                callbackFunction();
                            }
                            catch(ex){
                                callServiceError(ex);
                            }//end tc
                        }//end if
                    }//end if
                }//end if
            };
            
            ao.open("POST", serviceUrl, true);            
            ao.setRequestHeader("Content-Type", "text/xml");
            ao.setRequestHeader("soapaction", nameSpace + soapMethod);
            try{
                ao.send(soapEnvelope);
            }
            catch(ex){
                serviceCallError(ex);
            }//end tc
        }
        else{
            var soapParams = new Array();
            var headers = new Array();
            var soapVersion = 0;
            var object = nameSpace;
            
            if(serviceUrl.indexOf("http://") < 0)
                serviceUrl = document.location + serviceUrl;
            
            ao.transportURI = serviceUrl;
            ao.actionURI = nameSpace + soapMethod;
            
            for(var i=3; i<arguments.length; i++){
                var params = arguments[i].split("=");
                soapParams.push( new SOAPParameter(params[1],params[0]) );
            }//end for
            
            try{
                ao.encode(soapVersion, soapMethod, object, headers.length, headers, soapParams.length, soapParams);
            }
            catch(ex){
                serviceCallError(ex);
            }//end tc
        
            try{
                netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
            } 
            catch(ex){
                return false;
            }//end tc
            
            try{
                ao.asyncInvoke(
                    function(resp,call,status){

                    if(resp.fault)
                        return callServiceError(resp.fault);
                    if(!resp.body){
                        callServiceError("Service " + call.transportURI + " not found.");
                    }
                    else{
                        try{
                            callbackFunction(resp.body.firstChild.firstChild.firstChild.data);
                        }
                        catch(ex){
                            callServiceError(ex);
                        }//end tc
                    }//end if
                }
                );
            }
            catch(ex){
                serviceCallError(ex);
            }//end tc
                        
        }//end if
        
    }//end callService()
    
    this.setNameSpace = function(ns){
        nameSpace = ns;
    }//end setNameSpace()
    
    this.getNameSpace = function(){
        return ns;
    }//end getNameSpace()
    
}//end Masykur.Ajax()

Categories: AJAX | JavaScript
Permalink | Comments (17) | Post RSSRSS comment feed

Comments

Mara Mei Indonesia | Reply

Monday, February 18, 2008 4:37 PM

Mara Mei

Apa maksudnya ;

if(!ao.encode){

}

Ahmad Masykur United States | Reply

Monday, February 18, 2008 4:50 PM

Ahmad Masykur

Maksudnya adalah untuk pengecekan apakah browser mendukung pembungkusan SOAP sendiri seperti pada browser Netscape Navigator. Pembungkusan SOAP hanya dapat dilakukan oleh object SOAPCall. Jika browser mendukung object SOAPCall, maka tidak perlu dilakukan pembungkusan data manual yang dikirimkan pada request body.

busby seo challenge United States | Reply

Tuesday, August 26, 2008 11:32 AM

busby seo challenge

        try{return new ActiveXObject("Microsoft.XMLHTTP");}catch(ex){};
        try{return new SOAPCall();}catch(ex){}; ?

http://pinayspeak.com | http://alaminos.net

nahl Indonesia | Reply

Wednesday, September 10, 2008 1:43 AM

nahl

makasih bgt

laptop cases United States | Reply

Wednesday, September 17, 2008 10:06 PM

laptop cases

Wow nice Tech about computer ... very interesting.. thanks

busby seo test United States | Reply

Wednesday, October 01, 2008 11:47 PM

busby seo test

What a nice post... very interesting.. thanks for this my friend...

seo test United States | Reply

Tuesday, October 21, 2008 12:36 AM

seo test

Thanks for this code...

European Toxic Clan United States | Reply

Saturday, January 10, 2009 12:43 PM

European Toxic Clan

XMLHttpRequest (XHR) is a DOM API that can be used by JavaScript and other web browser scripting languages to transfer XML and other text data between a web server and a browser. This type of AJAX architecture should not be confused with (XDR) XMLDomainRequest which is a lightweight form of XMLHttpRequest design by Microsoft which doesn't utilize XML-RPC.

Mobil X Mobiltelefoner United States | Reply

Saturday, January 10, 2009 11:56 PM

Mobil X Mobiltelefoner

The XMLHttpRequest  object implements an interface exposed by a scripting engine that allows scripts to perform HTTP client functionality, such as submitting form data or loading data from a server.

hd United States | Reply

Monday, January 12, 2009 4:49 PM

hd

Wow nice Tech about computer ... very interesting.. thanks

party planning United States | Reply

Friday, January 16, 2009 10:47 AM

party planning

  

AJAX stands for Asynchronous JavaScript And XML.

AJAX is a type of programming made popular in 2005 by Google (with Google Suggest).

AJAX is not a new programming language, but a new way to use existing standards.

Neil United States | Reply

Thursday, January 29, 2009 4:34 PM

Neil

While the term Ajax was coined in 2005, alternative techniques for the asynchronous loading of content date back to the mid 1990s. Java applets were introduced in the first version of the Java language in 1995.

indojazz.net Indonesia | Reply

Friday, January 30, 2009 7:40 AM

indojazz.net

makasih atas review code nya
suwun mas ahmad
btw belajare kayak apa bisa diterima freeport
ato cuman bayangin tok ? (red, guyon)
sukses selalu untuk pengunjung masykur.web.id

Rockaway, NJ Mercedes Benz Repairs United Kingdom | Reply

Friday, February 06, 2009 12:49 AM

Rockaway, NJ Mercedes Benz Repairs

Reta's purchasing some items from a wholesaler's website. Each time she adds an item to the shopping cart, the website issues an XMLHttpRequest to save the latest cart contents. There's no form submission, so the item is added instantaneously, which saves Reta time as well as helping her understand what's going on.


http://www.carserviceautorepair.com/
European maintenance and repairs from brakes, tune ups, front end alignment to engine overhaul, we do it all.

wedding songs United States | Reply

Monday, February 09, 2009 5:35 PM

wedding songs

The acronym AJAX has thus changed to the term Ajax, which does not represent these specific technologies.

Birch Tire and Auto Service United Kingdom | Reply

Tuesday, February 10, 2009 3:25 AM

Birch Tire and Auto Service

Good Year, Toyo, Kumho and other great tire brands in stock.  All common factory maintenance services are available.

New Car Tires, Service, Maintenance and repairs United Kingdom | Reply

Tuesday, February 10, 2009 3:38 AM

New Car Tires, Service, Maintenance and repairs

There are a number of patterns about Web Services, but the important thing .... XMLHttpRequest has an abort() function which you should also invoke in a ...

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading