Skin:
Asynchronous Javascript And XML (AJAX) ---------------------------------------- Copyright © 2006-2007 Maborak Technologies Inc. (http://www.maborak.com) 2008-01-02 ----------------------------------------------------------------------------------- Tabla de Contenidos 1. Fundamentos 1.1. Introducción 1.2. Que NO es Ajax 1.3. Formas similares de conexiones asincronas 1.4. Javascript+DOM+XML+JSON 1.5. Síncrono Vs Asíncrono 2. Vida fácil 2.1. Editores 2.2. Navegadores 2.3. Depuradores 2.4. Bibliografía 3. Objeto XMLHttpRequest 3.1. Introducción 3.2. Instancia 3.3. Métodos 3.4. Propiedades 4. Código 4.1. Peticiones por método POST (paso a paso) 4.2. Peticiones por método GET 4.3. Respuesta text/plain 4.4. Respuesta text/xml 4.5. Peticiones síncronas 5. JSON ----------------------------------------------------------------------------------- 1. Fundamentos 1.1. Introducción Ajax es el acrónimo para [A]synchronous [J]avascript [A]nd [X]ML mediante la cual rutinas, datos, etc. son intercambiados con el servidor ( Apache/PHP, Tomcat/JSP, IIS/ASP ) sin necesidad de recargar toda la página web o terminar un proceso Javascript (asíncrono). De esta forma actualizas/quitas/agregas solo las partes necesarias de tu aplicación, ahorrando ancho de banda y haciendolo dinámico. Es a lo que hoy en día se lo llama WEB 2.0. 1.2. Que NO es Ajax Ajax no es: * Un módulo de Apache * Una extensión PHP * Un plugin * Una tecnología, * Un archivo * Un programa * Un script 1.3. Formas similares de conexiones asincronas * Javascript Remote Scripting (JSRS) * SOAP * XML-RPC (http://www.xmlrpc.com/) 1.4. Javascript+DOM+XML+JSON+IFRAME Para aprender a usar esta metodología no esta demás decir que tus conocimientos sobre Javascript deben estar por lo menos en un nivel intermedio caso contrario puedes arruinar tu sistema o la navegabilidad del mismo. Como dicen "si quieres manejar un ferrari F-1 mínimo debes saber manejar". Para aprovechar al máximo este método debes tener un conocimiento claro y limpio de la manipulacion de elementos DOM del navegador agregar, quitar, modificar el comportamiento del mismo. Para el intercambio de datos Cliente-Servidor es necesario (a largo alcanze) utilizar alguna tecnología como JSON (JavaScript Object Notation) o XML ya que el flujo que vayamos a necesitar puede consumir muchos recursos y necesitaremos dividir los procesos acorde a las necesidades especificas de la aplicación. Ya que Ajax no es una tecnología en el pasado se utilizó "hacks" para realizar peticiones asíncronas una de ellas era el uso de Iframes. La idea consistía en cargar en un iframe oculto la url del servidor enviando datos por GET o por algun formulario POST y luego leer el contenido resultante del iframe y aplicarlo a lo que corresponda. 1.4. Síncrono Vs Asíncrono Javascript interpreta el código linea por linea, esto quiere decir que no se pasa a interpretar la siguiente linea si la actual no ha terminado su proceso. Por ejemplo:

------------- Code begin -------------
	1. var i = 9898;
	2. alert(i);
	3. var j = 22;
	4. alert(j);
------------- Code end -------------
En este ejemplo el interprete se detiene en la linea 2 mostrando el alert y se pasará a la linea 3 cuando se cierre el alert y así sucesivamente. Esto es un proceso síncrono. En el caso de asíncrono el interprete no se pone a la espera de que el proceso termine(se ejecuta el proceso en background) y pasa a la siguiente línea para su interprete. XMLHttpRequest no es el único objeto asincrono, también tenemos a la función setTimeOut() y setInterval(). XMLHttpRequest soporta peticiones síncronas y asíncronas, se usa una conexión asíncrona cuando la aplicación hará multiples peticiones de forma independiente, pero en el caso de simplemente tener una petición a la vez, es mucho mas fácil usar una petición sincrona (se explicará mas adelante). 2. Vida fácil 2.1. Editores Pueden usar cualquier editor para sus apicaciones dinámicas, algunos se sienten cómodos usando Ultraedit pero personalmente siento mayor comodidad usando: Windows: * Zend Studio * Komodo IDE Editor * Aptana IDE * Scite Linux: * Vim ( Es el que yo uso ) * Aptana IDE * Zend Studio * Scite De todos estos editores Aptana y Komodo están orientados a Ajax o Aplicaciones Ricas de Internet ya que tienes su propio depurador y se acopla perfectamente con muchos frameworks conocidos como Mootools, Prototype, etc. 2.2. Navegadores * Mozilla Firefox (http://www.mozilla.org), Navegador recomendado por excelencia ya que te facilita muchisimo la depuración, edición en caliente(Firebug), edición de la hoja de estilos(Firebug, Web developer addon), rastreo de Headers, etc. * Microsoft Internet Explorer, los depuradores para Internet Explorer son muy pobres comparados con las herramientas de Mozilla Firefox. * Opera (http://www.opera.com), excelente navegador con interprete javascript muy estricto. Úsese para casos de prueba * Safari (http://www.apple.com/safari), nevagador web usando KHTML para su interprete estricto. Úsese para casos de prueba. Nota: Solo existen 4 tipos de navegadores: 1.- Navegadores basados en Gecko de Mozilla (Mozilla firefox, Netscape, K-meleon, Epiphany). 2.- Microsoft Internet Explorer. 3.- Opera. 4.- Navegadores basados en KHTML (Safari, Konqueror). Existen muchos navegadores, pero generalmente estan basados en uno de estos motores para interpretar Html,Javascript,Css. Con una aplicación compatible en estos 4 motores, oficialmente tienes una aplicación Crossbrowser. 2.3. Depuradores No puedes tener una vida tranquila y fácil si no usas un depurador para tus aplicaciones entre ellas menciono. Windows: * Firebug (http://www.getfirebug.com) Extensión de Mozilla Firefox. * Firebug Minimal (http://www.getfirebug.com) Archivo javascript integrado en cualquier navegador. * Web Developer (http://addons.mozilla.org) Extensión de Mozilla Firefox. * IE Inspector (http://www.ieinspector.com) Integrado en Microsoft Internet Explorer. * DebugBar (http://www.debugbar.com) Integrado en Microsoft Internet Explorer. * Aptana Debugger (http://www.aptana.org) Integrado en Aptana Editor para Mozilla Firefox. Linux * Firebug (http://www.getfirebug.com) Extensión de Mozilla Firefox. * Web Developer (http://addons.mozilla.org) Extensión de Mozilla Firefox. * Aptana Debugger (http://www.aptana.org) Integrado en Aptana Editor para Mozilla Firefox. 2.4. Bibliografía * Creating Web Pages with Asynchronous JavaScript and XML By: Edmond Woychowsky Publisher: Prentice Hall Pub Date: Agosto 08, 2006 Pages: 432 * Ajax Hacks By: Bruce W. Perry Publisher: O'reilly Pud Date: Marzo 2006 Pages: 438 * Ajax Design Patterns By: Michael Mahemoff Publisher: O'Reilly Pub Date: Junio 2006 Pages: 655 * Ajax for Web Application Developers By: Kris Hadlock Publisher: Sams Pub Date: October 30, 2006 Pages: 288 * Ajax Bible By: Steven Holzner Publisher: John Wiley & Sons Pub Date: 2007 Pages: 716 * Javascript Phrasebook: Essential Code and Commands By: Christian Wenz Publisher: Sams Pub Date: August 28, 2006 Pages: 240 * Javascript Bible, Gold Edition By: Danny Goodman Publisher: Hungry Minds, Inc. Pages: 2177 * Javascript Aplication Cookbook By: Jerry Brandenbaugh Publisher: O'Reilly Pub Date: Septembre 1999 Pages: 476 * DOM Scripting By: Jeremy Keith Publisher: Friendsoft Pages: 369 Por lo menos tienes que leer uno de estos buenísimos libros, recomiendo (Ajax Hacks, Javascript Bible). Si no alcanzaron a leer alguno de estos, ni sueñen en tener una aplicación mantenible, escalable y crossbrowser. 3. Objeto XMLHttpRequest 3.1. Introducción Ya que Ajax es un método y no una tecnología usaremos uno de esos métodos, el cual es usar el Objeto nativo ( Mozilla/Opera/Safari/Gecko ) y ActiveX ( Microsoft Internet Explorer ) llamado XMLHttpRequest, mediante el cual puedes hacer peticiones Asíncronas y Síncronas. 3.2. Instancia Lamentablemente el Objeto XMLHttpRequest se lo instancia de diferentes formas según el navegador web, por lo tanto haremos un Objeto XMLHttpRequest Crossbrowser ( que funcione en todos los navegadores por igual ).

------------- Code begin -------------
var XMLHttpObject = function()
{
	try{
		var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	}
	catch(e)
	{
		try
		{
			var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(e)
		{
			var xmlhttp = false;
		}
	}
	return (!xmlhttp && typeof XMLHttpRequest!='undefined')?
	new XMLHttpRequest():xmlhttp || new function(){};
}
------------- Code end -------------
Instanciamos al objeto.

------------- Code begin -------------
    var rpc = new XMLHttpObject();
------------- Code end -------------
Con esto ya tenemos el objeto para trabajar, ahora detallaré sus métodos y propiedades. 3.3. Métodos --------------------------------------------------------------------------------------- | Método | Descripción | |-------------------------------------------------------------------------------------| | | | | abort() | Cancela la actual peticion HTTP. | | | | |---------------------------------|---------------------------------------------------| | | | | getAllResponseHeaders(label) | Retorna en una cadena todas las cabeceras HTTP. | | | | |---------------------------------|---------------------------------------------------| | | | | getResponseHeader(label) | Retorna un valor específico de las cabeceras HTTP| | | | |---------------------------------|---------------------------------------------------| | | | | open(method,URL,asynchFlag) | Inicializa la peticion XMLHttp. | | | | |---------------------------------|---------------------------------------------------| | | | | send(content) | Envia la peticion al servidor esperando su | | | respuesta. | | | | |---------------------------------|---------------------------------------------------| | | | | setRequestHeader(label,value) | Añade una cabecera y un valor HTTP al momento de | | | enviar el contenido. | --------------------------------------------------------------------------------------- 3.4. Propiedades --------------------------------------------------------------------------------------- | Propiedad | Descripción | |-------------------------------------------------------------------------------------| | | | | status | Contiene el código de estado retornado por la | | | peticion HTTP. Read-only. | | | | | | Lista de estados: | | | | | | 200 OK | | | 201 Created | | | 204 No Content | | | 205 Reset Content | | | 206 Partial Content | | | 400 Bad Request | | | 401 Unauthorized | | | 403 Forbidden | | | 404 Not Found | | | 405 Method Not Allowed | | | 406 Not Acceptable | | | 407 Proxy Authentication Required | | | 408 Request Timeout | | | 411 Length Required | | | 413 Requested Entity Too Large | | | 414 Requested URL Too Long | | | 415 Unsupported Media Type | | | 500 Internal Server Error | | | 501 Not Implemented | | | 502 Bad Gateway | | | 503 Service Unavailable | | | 504 Gateway Timeout | | | 505 HTTP Version Not Supported | | | | |---------------------------------|---------------------------------------------------| | | | | statusText | Contiene la de estado retornado por la peticion | | | HTTP. | | | Por ejemplo: | | | | | | 200-> retorna "OK" | | | 501-> retorna "Not Implemented" | | | | | | Read-only. | |---------------------------------|---------------------------------------------------| | | | | readyState | Contiene el estado actual de la peticion HTTP. | | | | | | 0 uninitialized | | | 1 loading | | | 2 loaded | | | 3 interactive | | | 4 complete | | | | | | Read-only. | |---------------------------------|---------------------------------------------------| | | | | onreadystatechange | Función a la que se llamara cuando el objeto | | | cambie de estado (leer readyState). | | | | | | Read/Write. | |---------------------------------|---------------------------------------------------| | | | | responseText | Contiene la respuesta del servidor en texto | | | plano. | | | | | | Read-only. | |---------------------------------|---------------------------------------------------| | | | | responseXML | Contiene la respuesta del servidor como documento| | | XML. | | | | | | Read-only | --------------------------------------------------------------------------------------- 4. Código 4.1. Peticiones por método POST (paso a paso) Para este primer ejemplo haremos una peticion por el método POST a nuestro servidor. 1.- Instanciamos el objeto

------------- Code begin -------------
var XMLHttpObject = function()
{
	try{
		var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	}
	catch(e)
	{
		try
		{
			var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(e)
		{
			var xmlhttp = false;
		}
	}
	return (!xmlhttp && typeof XMLHttpRequest!='undefined')?
	new XMLHttpRequest():xmlhttp || new function(){};
}
var rpc = new XMLHttpObject();
------------- Code end -------------
2.- Iniciamos la petición definiendo el método ("POST") la url ("ejemplo1_server.php") y la bandera de petición asincrona (true).

------------- Code begin -------------
rpc.open("POST","ejemplo1_server.php",true);
rpc.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
------------- Code end -------------
Nota: Todo método POST debe tener el header: "Content-Type","application/x-www-form-urlencoded" encodeURI() Devuelve una cadena en la que todos los caracteres no-alfanuméricos excepto -_. han sido reemplazados con un signo de porcentaje (%) seguido por dos dígitos hexadecimales y los espacios son codificados como signos de suma (+). Esta es la misma codificación usada en los datos publicados desde un formulario WWW, es decir, el mismo mecanismo usado para el tipo de medios application/x-www-form-urlencoded. Este mecanismo difiere de la codificación RFC1738 (vea encodeURIComponent()) en que, por razones históricas, los espacios son codificados como signos de suma (+). Esta función es conveniente cuando se codifica una cadena a ser usada como la parte de consulta de una URL, como método práctico para pasar variables a la siguiente página. 3.- Enviamos la peticion al servidor en espera de respuesta.

------------- Code begin -------------
rpc.send(encodeURI("param1=parametro1&param2=parametro2&param3=Hola mundo"));
------------- Code end -------------
Dentro del contenido enviaremos variables como cadena(separadas por &). var1=algo var2=otro quedando var1=algo&var2=otro 4.- Definimos la función que se llamará en cada cambio de estado y condicionamos que si el estado (rpc.readyState) sea igual a 4 mostr emos un alert con la respuesta del servidor (rpc.responseText).

------------- Code begin -------------
rpc.onreadystatechange=function()
{
	if(rpc.readyState===4)
	{
		alert(rpc.responseText);
	}
}
------------- Code end -------------
Y es todo, con estos 4 simples pasos hemos hecho una peticion HTTP de forma asincrona. Ahora todo en uno. ejemplo1.html

------------- Code begin -------------
<html>
<head>
<script type="text/javascript">
	var XMLHttpObject = function()
	{
		try{
			var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch(e)
		{
			try
			{
				var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(e)
			{
				var xmlhttp = false;
			}
		}
		return (!xmlhttp && typeof XMLHttpRequest!='undefined')?
		new XMLHttpRequest():xmlhttp || new function(){};
	}
	var rpc = new XMLHttpObject();
	rpc.open("POST","ejemplo1_server.php",true);
	rpc.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	rpc.send(encodeURI("param1=parametro1&param2=parametro2&param3=Hola mundo"));
	rpc.onreadystatechange=function()
	{
		if(rpc.readyState===4)
		{
			alert(rpc.responseText);
		}
	}
</script>
</head>
</html>
------------- Code end -------------
ejemplo1_server.php

------------- Code begin -------------
<?php
echo "variables  POST:\n";
print_r($_POST);
echo "variables  GET:\n";
print_r($_GET);
?>
------------- Code end -------------
El resultado es:

------------- Code begin -------------
variables  POST:
Array
(
    [param1] => parametro1
    [param2] => parametro2
    [param3] => Hola mundo
)
variables  GET:
Array
(
)
------------- Code end -------------
Con este pequeño código ya hemos tenido un primer acercamiento a este método. Para entender mejor el código y monitorear las peticiones, pueden activar el depurador Firebug (explicado mas arriba). 4.2. Peticiones por método GET Hacer una petición por método GET es igual de simple que el método POST con diferencia de un par de líneas (se daran cuenta cuales). ejemplo2.html

------------- Code begin -------------
<html>
<head>
<script type="text/javascript">
	var XMLHttpObject = function()
	{
		try{
			var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch(e)
		{
			try
			{
				var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(e)
			{
				var xmlhttp = false;
			}
		}
		return (!xmlhttp && typeof XMLHttpRequest!='undefined')?
		new XMLHttpRequest():xmlhttp || new function(){};
	}
	var rpc = new XMLHttpObject();
	rpc.open("GET","ejemplo1_server.php?param1=parametro1¶m2=parametro2¶m3=Hola mundo",true);
	rpc.send(null);
	rpc.onreadystatechange=function()
	{
		if(rpc.readyState===4)
		{
			alert(rpc.responseText);
		}
	}
</script>
</head>
<body>
</body>
</html>
    
ejemplo2_server.php

------------- Code begin -------------
<?php
echo "variables  POST:\n";
print_r($_POST);
echo "variables  GET:\n";
print_r($_GET);
?>
------------- Code end -------------
El resultado por GET:

------------- Code begin -------------
variables  POST:
Array
(
)
variables  GET:
Array
(
    [param1] => parametro1
    [param2] => parametro2
    [param3] => Hola mundo
)
------------- Code end -------------
4.3. Respuesta text/plain Para procesar la respuesta del servidor como texto plano se debe usar el método responseText(), de esta manera podemos manipular la respuesta en nuestros objetos DOM o bien recibir texto plano en formato JSON y manipularlo directamente como datos de aplicación. En este ejemplo recibiremos texto plano y lo incrustaremos en una parte (un bloque DIV) de nuestra página HTML. ejemplo3.html

------------- Code begin -------------
<html>
<head>
<script type="text/javascript">
var XMLHttpObject = function()
{
	try{
		var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	}
	catch(e)
	{
		try
		{
			var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(e)
		{
			var xmlhttp = false;
		}
	}
	return (!xmlhttp && typeof XMLHttpRequest!='undefined')?
	new XMLHttpRequest():xmlhttp || new function(){};
}
var incrustar=function()
{
	var rpc = new XMLHttpObject();
	var div	= document.getElementById("target");
	div.innerHTML="Cargando......";
	rpc.open("POST","ejemplo3_server.php",true);
	rpc.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	rpc.send('a=1');
	rpc.onreadystatechange=function()
	{
		if(rpc.readyState===4)
		{
			div.innerHTML = rpc.responseText;
		}
	}
}
</script>
<style>
body
{
	font:normal 11px sans-serif;
}
</style>
</head>
<body>
Vestibulum semper. Nullam non odio. Aliquam quam. Vestibulum semper. Nullam non odio.<br>
Aliquam quam. Vestibulum semper. Nullam non odio. Aliquam quam. Vestibulum semper.<br>
Nullam non odio. Aliquam quam. Vestibulum semper. Nullam non odio. Aliquam quam.<br>
<div id="target" style="border:1px solid #EEE;padding:5px;color:#006699;">
</div>
<a href="#" onclick="incrustar(); return false;">Solicitar datos</a><br>
Vestibulum semper. Nullam non odio. Aliquam quam. Vestibulum semper. Nullam non odio.<br>
Aliquam quam. Vestibulum semper. Nullam non odio. Aliquam quam. Vestibulum semper.<br>
Nullam non odio. Aliquam quam. Vestibulum semper. Nullam non odio. Aliquam quam.<br>
</body>
</html>
------------- Code end -------------
ejemplo3_server.php

------------- Code begin -------------
Vestibulum semper. <b>Nullam non odio</b>. Aliquam quam. Vestibulum semper.
Aliquam quam. Vestibulum semper. <u>nullam non odio. Aliquam quam</u>.
<ol>
	<li>Blabla</li>
	<li>Blabla</li>
	<li>Blabla</li>
	<li>Blabla</li>
</ol>
Nullam non odio. Aliquam quam. Vestibulum semper. Nullam non odio. Aliquam quam.
------------- Code end -------------
4.4. Respuesta text/xml Para procesar la respuesta se debe usar el método responseXML(),para convertirlo en un objeto XMLDocument pudiendo acceder a sus nodos y atributos con nodo.getElementsByTagName("nodo") y así de forma recursiva. * DocumentXML.getElementsByTagName("nodo"), Devuelve un Array de Nodos. * Nodo[0].firstChild.nodeValue, Devuelve el contenido del Nodo. * Nodo[0].getAttribute("atributo"), Devuelve el valor de un atributo del actual Nodo. * Nodo[0].attributes, Devuelve un Array de atributos del actual Nodo. * Nodo[0].attributes[0].nodeValue, Devuelve el valor de un atributo en el indice actual. Se puede usar Firebug para acceder a todas las propiedades y métodos de los Nodos de esta forma: 1.- Guardar en una variable global el contenido del Nodo o XMLDocument window.inspector = Nodo[0] o window.inspector = rpc.responseXML 2.- Abrir la pestaña Script en Firebug y añadir a New watch expression la cadena window.inspector 3.- Navegar por el arbol DOM que genera Firebug. Para evitar errores con el objeto XML se debe enviar Headers indicando que se va a responder con un documento XML. * <?xml version="1.0" ?> : en caso de ser un documento.xml. * header('Content-Type: text/xml'); : En el caso de crear el documento XML mediante PHP. * Enviar cabeceras text/xml de acuerdo a la tecnología usada en el servidor. También se puede usar Firebug para examinar los nodos como DOM Object. ejemplo4.html

------------- Code begin -------------
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
var XMLHttpObject = function()
{
	try{
		var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	}
	catch(e)
	{
		try
		{
			var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(e)
		{
			var xmlhttp = false;
		}
	}
	return (!xmlhttp && typeof XMLHttpRequest!='undefined')?
	new XMLHttpRequest():xmlhttp || new function(){};
}
window.onload=function()
{
	var rpc = new XMLHttpObject();
	var target = document.getElementById("target");
	rpc.open("POST","musica.xml",true);
	rpc.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	rpc.send();
	rpc.onreadystatechange=function()
	{
		if(rpc.readyState===4)
		{
			var DocumentXML = rpc.responseXML;
			var banda = DocumentXML.getElementsByTagName("banda");
			parent.window.ss=banda;
			for(var i=0;i<banda.length;i++)
			{
				target.innerHTML+= banda[i].firstChild.nodeValue+"<br>";
				target.innerHTML+= "::Género:"+banda[i].getAttribute("genero")+"<br>";
			}
			target.innerHTML+="<br><br>------------ Response Text ------------<br>";
			target.appendChild(document.createTextNode(rpc.responseText));
		}
	}
}
</script>
</head>
<body>
<pre id="target">
</pre>
</body>
</html>
------------- Code end -------------
musica.xml

------------- Code begin -------------
<?xml version="1.0" ?>
<listado>
	<banda genero="Electro dark"><![CDATA[Hocico]]></banda>
	<banda genero="Gothic Metal"><![CDATA[Lacuna coil]]></banda>
	<banda genero="Gothic Rock"><![CDATA[Zeraphine]]></banda>
</listado>
------------- Code end -------------
4.5. Peticiones síncronas Para realizar una petición síncrona: 1.- Poner en false el tercer parametro del método open(method,URL,asynchFlag). ¡Importante! 2.- La propiedad onreadystatechange ya no es leída porque en la petición sincrona no cambia la propiedad readyState. Tomarlo como Nota. ejemplo5.html

------------- Code begin -------------
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
var XMLHttpObject = function()
{
	try{
		var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	}
	catch(e)
	{
		try
		{
			var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(e)
		{
			var xmlhttp = false;
		}
	}
	return (!xmlhttp && typeof XMLHttpRequest!='undefined')?
	new XMLHttpRequest():xmlhttp || new function(){};
}
var asin = function()
{
	var rpc = new XMLHttpObject();
	var target = document.getElementById("target");
	target.innerHTML="Loading......";
	rpc.open("POST","ejemplo1_server.php",false);
	rpc.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	rpc.send(encodeURI("param1=parametro1¶m2=parametro2¶m3=Hola mundo"));
	target.innerHTML = rpc.responseText;
}
</script>
</head>
<body>
<pre>
<a href="#" onclick="asin(); return false;">Cargar petición síncrona</a>
</pre>
<pre id="target">
</pre>
</body>
</html>
------------- Code end -------------