En el ultimo tutoriales en linea anterior de Ajax con jQuery, JSON y PHP. Hoy vengo con lo mismo pero sin jQuery, es decir, vamos a ver como trabajar con Ajax y JSON utilizando jаvascript puro, sin ningún framework ni biblioteca. Volvemos a los orígenes de tecnología Ajax: crear un objeto XMLHttpRequest con el que jаvascript puede comunicarse con el servidor de forma asíncrona intercambiando datos entre el cliente y el servidor sin interferir en el comportamiento actual de la página. Comúnmente, la respuesta desde servidor es utilizada para realizar manipulaciones posteriores en el DOM; por ejemplo, cambiar el contenido mostrado en la página.
El objeto XMLHttpRequest es el responsable de comunicarse con el servidor de forma asíncrona. Crear este objeto necesita, como mínimo, la URL que se va a solicitar al servidor, la cuál puede ser cualquier tipo de recurso, y no sólo XML (aunque su nombre sea XMLHttpRequest). Por ejemplo, la URL solicitada podría devolver HTML, JavaSript, CSS, texto plano, imágenes o, lo que nos ocupa en este tutorial, JSON.
Ejemplo con método GET
En el método GET, los parámetros de la solicitud se añaden a la URL como query string, es decir, se añade a la URL una cadena del tipo param1=value1¶m2=value2:
Si se utiliza el método POST, la solicitud necesita ser enviada como si fuera un formulario (Content-type: application/x-www-form-urlencoded o multipart-form-data). Los datos se envían, al igual que antes en el ejemplo con el método GET, como query string pero en este caso se envían como parámetro del método XMLHttpRequest.send y no como parte de la URL:
Había dicho que el formato de los datos enviados en la solicitud POST tiene que ser tipo query string (key=valor&key2=valor2) y que se tienen que enviar como un formulario (Content-type: application/x-www-form-urlencoded). Bien, no es cierto.
En realidad podemos hacer un POST con los datos en cualquier formato, por ejemplo en JSON:
Ya sabemos cómo enviar la solicitud al servidor. Para recibir la respuesta se utiliza la propiedad XMLHttpRequest.onreadystatechange para ejecutar una función cuándo XMLHttpRequest.readyState cambia de valor. El valor de readyState que más nos interesa es 4; este valor indica que la solicitud Ajax ha concluido y la respuesta desde el servidor está disponible en XMLHttpRequest.responseText:
Aunque el propio nombre Ajax signifique Asynchronous jаvascript And XML y el objeto utilizado para la comunicación cliente-servidor se llame XMLHttpRequest, con Ajax se puede solicitar en realidad cualquier tipo de datos: XML, HTML, texto plano, jаvascript, CSS y cualquier otro formato que se te pueda ocurrir, incluido el formato JSON que hoy en día es el formato de elección para intercambio de datos cuándo se trabaja con Ajax.
JSON son las siglas de jаvascript Object Notation (Notación de Objeto jаvascript). Los objetos jаvascript tienen una estructura compuesta por pares key : value (clave : valor):
// La variable misDatos contiene un objeto jаvascript
var misDatos = {"nombre" : "Antonio", "apellidos" : "Molina Ballesteros", "edad" : 35};
La respuesta JSON en una solicitud Ajax es un string, no es un objeto jаvascript sino una cadena de texto con notación de objeto jаvascript, esto es JSON. Es necesario convertir esta cadena a un objeto antes de intentar trabajar con los datos. Esta conversión se realiza con el método JSON.parse. El siguiente ejemplo es exactamente igual que el anterior pero la variable misDatos es un string (fíjate en las comillas) y es necesario aplicar JSON.parse para convertirlo en un objeto jаvascript:
Ya hemos visto como construir una solicitud Ajax y como trabajar con objetos en jаvascript de forma básica, así que estamos listos para combinar ambos. Vamos a ver un ejemplo en el que se envía una solicitud Ajax a un script PHP que devuelve información en formato JSON. Voy a utilizar el mismo ejemplo que en el tutorial mencionado al principio de este tutorial, tan sólo cambia el jаvascript utilizado, el PHP es exactamente igual y no lo voy a repetir aquí, aunque puedes descargarte el ejemplo completo más abajo.
Descargar el ejemplo completo
Construyendo el objeto XMLHttpRequest y enviando la solicitud
El objeto XMLHttpRequest es el responsable de comunicarse con el servidor de forma asíncrona. Crear este objeto necesita, como mínimo, la URL que se va a solicitar al servidor, la cuál puede ser cualquier tipo de recurso, y no sólo XML (aunque su nombre sea XMLHttpRequest). Por ejemplo, la URL solicitada podría devolver HTML, JavaSript, CSS, texto plano, imágenes o, lo que nos ocupa en este tutorial, JSON.
Ejemplo con método GET
En el método GET, los parámetros de la solicitud se añaden a la URL como query string, es decir, se añade a la URL una cadena del tipo param1=value1¶m2=value2:
// Definimos la URL que vamos a solicitar via Ajax
var ajax_url = "http://mysite.com/json/data.json";
// Definimos los parámetros que vamos a enviar
var params = "parametro=valor&otro_parametro=otro_valor";
// Añadimos los parámetros a la URL
ajax_url += '?' + params;
// Creamos un nuevo objeto encargado de la comunicación
var ajax_request = new XMLHttpRequest();
// Definimos como queremos realizar la comunicación
ajax_request.open( "GET", ajax_url, true );
//Enviamos la solicitud
ajax_request.send();
Parémonos un momento en el método XMLHttpRequest.open. Este método admite varios parámetros, que son: (os remito a la documentación para más informatión3)- método: el método HTTP a utilizar en la solicitud Ajax. GET o POST, en el ejemplo anterior fue GET.
- url: dirección URL que se va a solicitar, o lo que es lo mismo, la URL a la que se va enviar la solicitud.
- async: true (asíncrono) o false (síncrono). Es opcional y el valor por defecto es true. Hay quien recomienda ponerlo siempre por si no se respeta el valor por defecto.
Ejemplo con método POST
Si se utiliza el método POST, la solicitud necesita ser enviada como si fuera un formulario (Content-type: application/x-www-form-urlencoded o multipart-form-data). Los datos se envían, al igual que antes en el ejemplo con el método GET, como query string pero en este caso se envían como parámetro del método XMLHttpRequest.send y no como parte de la URL:
// Definimos la URL que vamos a solicitar via Ajax
var ajax_url = "http://mysite.com/json/data.json";
// Definimos los parámetros que vamos a enviar
var params = "parametro=valor&otro_parametro=otro_valor";
// Creamos un nuevo objeto encargado de la comunicación
var ajax_request = new XMLHttpRequest();
// Definimos como queremos realizar la comunicación
ajax_request.open( "POST", ajax_url, true );
// Ponemos las cabeceras de la solicitud como si fuera un formulario, necesario si se utiliza POST
ajax_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//Enviamos la solicitud junto con los parámetros
ajax_request.send( params );
Enviar una solicitud POST con JSON
Había dicho que el formato de los datos enviados en la solicitud POST tiene que ser tipo query string (key=valor&key2=valor2) y que se tienen que enviar como un formulario (Content-type: application/x-www-form-urlencoded). Bien, no es cierto.
En realidad podemos hacer un POST con los datos en cualquier formato, por ejemplo en JSON:
// El JSON a enviar
var myjson = '{ "key" : "value", "key1" : "value1", "key2" : "value2" }'
var ajax_request = new XMLHttpRequest();
ajax_request.open( "POST", ajax_url, true );
// Establecer la cabecera Content-Type apropiada
ajax_request.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
// Enviar la solicitud
ajax_request.send( myjson );
Pero PHP seguirá esperando que el cuerpo de la solicitud sea un query string. Al recibir un cuerpo con otro formato, no podremos acceder desde PHP a esos datos en la superglobal $_POST como es habitual. Tendremos que acceder directamente al cuerpo de la solicitud y decodificar el JSON:/// Obtenemos el json enviado
$data = file_get_contents('php://input');
// Los convertimos en un array
$data = json_decode( $data, true );
Por eso decía que los datos se debían enviar como query string, porque en PHP no tiene mucho «sentido» enviarlos en otros formatos. Sin embargo, puede ser apropiado si en el servidor se utiliza otro lenguaje. Por ejemplo, enviar JSON mediante POST puede ser apropiado para servidores que utilicen Node.js.Recepción de la respuesta
Ya sabemos cómo enviar la solicitud al servidor. Para recibir la respuesta se utiliza la propiedad XMLHttpRequest.onreadystatechange para ejecutar una función cuándo XMLHttpRequest.readyState cambia de valor. El valor de readyState que más nos interesa es 4; este valor indica que la solicitud Ajax ha concluido y la respuesta desde el servidor está disponible en XMLHttpRequest.responseText:
// Definimos la URL que vamos a solicitar via Ajax
var ajax_url = "http://mysite.com/json/data.json";
// Definirmos los parámetros que vamos a enviar
var params = "parametro=valor&otro_parametro=otro_valor";
// Añadimos los parámetros a la URL
ajax_url += '?' + params;
// Creamos un nuevo objeto encargado de la comunicación
var ajax_request = new XMLHttpRequest();
// Definimos una función a ejecutar cuándo la solicitud Ajax tiene alguna información
ajax_request.onreadystatechange = function() {
// readyState es 4
if (ajax_request.readyState == 4 ) {
// Analizaos el responseText que contendrá el JSON enviado desde el servidor
var jsonObj = JSON.parse( ajax_request.responseText );
// La variable jsonObj ahora contiene un objeto con los datos recibidos
}
}
// Definimos como queremos realizar la comunicación
ajax_request.open( "GET", ajax_url, true );
//Enviamos la solicitud
ajax_request.send();
Trabajando con el formato JSON en jаvascript
Aunque el propio nombre Ajax signifique Asynchronous jаvascript And XML y el objeto utilizado para la comunicación cliente-servidor se llame XMLHttpRequest, con Ajax se puede solicitar en realidad cualquier tipo de datos: XML, HTML, texto plano, jаvascript, CSS y cualquier otro formato que se te pueda ocurrir, incluido el formato JSON que hoy en día es el formato de elección para intercambio de datos cuándo se trabaja con Ajax.
JSON son las siglas de jаvascript Object Notation (Notación de Objeto jаvascript). Los objetos jаvascript tienen una estructura compuesta por pares key : value (clave : valor):
{key : value, key2 : value2, key3 : value3, ...}
En el siguiente ejemplo la variable misDatos es un objeto jаvascript y tiene tres elementos cuyas key son nombre, apellidos y edad, y se puede acceder a sus valores con misDatos.name, misDatos.apellidos y misDatos.edad.// La variable misDatos contiene un objeto jаvascript
var misDatos = {"nombre" : "Antonio", "apellidos" : "Molina Ballesteros", "edad" : 35};
console.log( misDatos.nombre );
console.log( misDatos.apellidos );
console.log( misDatos.edad );
Los objetos pueden ser multidimensionales; por ejemplo:{
key : value,
key2 : {
subkey : subvalue,
subkey2 : subvalue2
}
}
Y se accede a los subkeys como jsonObj.key2.subkey, jsonObj.key2.subkey2, etc:// La variable misDatos contiene un objeto jаvascript
var misDatos = {
"nombre" : "Alex",
"apellidos" : "Agustin e...",
"edad" : 35,
"direccion" : {
"calle" : "Gran Via, 3",
"ciudad" : "Lanzarote"
}
};
console.log( misDatos.nombre );
console.log( misDatos.apellidos );
console.log( misDatos.edad );
console.log( misDatos.direccion.calle );
console.log( misDatos.direccion.ciudad );
JSON.parse
La respuesta JSON en una solicitud Ajax es un string, no es un objeto jаvascript sino una cadena de texto con notación de objeto jаvascript, esto es JSON. Es necesario convertir esta cadena a un objeto antes de intentar trabajar con los datos. Esta conversión se realiza con el método JSON.parse. El siguiente ejemplo es exactamente igual que el anterior pero la variable misDatos es un string (fíjate en las comillas) y es necesario aplicar JSON.parse para convertirlo en un objeto jаvascript:
// La variable misDatos es un string en notación JSON, pero no un objeto
var misDatos = '{ "nombre" : "Antonio", "apellidos" : "Molina Ballesteros", "edad" : 35, "direccion" : { "calle" : "Gran Via, 2", "ciudad" : "Madrid"} }';
// Se pasa el string a un objeto JSON
var jsonObj = JSON.parse( misDatos );
// Ahora, la variable jsonObj contiene el valor de cada key accesible en la forma jsonObj.key
console.log( jsonObj.nombre );
console.log( jsonObj.apellidos );
console.log( jsonObj.edad );
console.log( jsonObj.direccion.calle );
console.log( jsonObj.direccion.ciudad );
Ejemplo AJAX e interacción con PHP
Ya hemos visto como construir una solicitud Ajax y como trabajar con objetos en jаvascript de forma básica, así que estamos listos para combinar ambos. Vamos a ver un ejemplo en el que se envía una solicitud Ajax a un script PHP que devuelve información en formato JSON. Voy a utilizar el mismo ejemplo que en el tutorial mencionado al principio de este tutorial, tan sólo cambia el jаvascript utilizado, el PHP es exactamente igual y no lo voy a repetir aquí, aunque puedes descargarte el ejemplo completo más abajo.
<!DOCTYPE html>
<html lang="es-ES">
<head>
<meta charset="UTF-8">
<script>
//getdeails será nuestra función para enviar la solicitud ajax
var getdetails = function( id ){
// Definimos la URL que vamos a solicitar via Ajax
var ajax_url = "personas.php";
// Definimos los parámetros que vamos a enviar
// Debería trabajar en hacer esto un poco más limpio, de momento vale para hacer funcionar el ejemplo
var params = '';
id = JSON.parse(id).toString();
id = id.split(",");
if( id.length > 1 ) {
//Si hay más de un id, enviar como query string array
for( elem in id ) {
params += "id[]=" + id[elem] +"&";
}
} else {
params = "id=" + id;
}
//Añadimos los parámetros a la URL
ajax_url += '?' + params;
// Creamos un nuevo objeto encargado de la comunicación
var ajax_request = new XMLHttpRequest();
// Definimos una función a ejecutar cuándo la solicitud Ajax tiene alguna información
ajax_request.onreadystatechange = function() {
// see readyState es 4, proseguir
if (ajax_request.readyState == 4 ) {
// Analizaos el responseText que contendrá el JSON enviado desde el servidor
var response = JSON.parse( ajax_request.responseText );
if( response.success ) {
var output = "<h1>" + response.data.message + "</h1>";
//recorremos cada usuario
for ( user in response.data.users ) {
output += "<h2>Detalles del usuario " + response.data.users[user].ID + "</h2>";
//recorremos los valores de cada usuario
for ( userdata in response.data.users[user] ) {
output += '<ul>';
output += '<li>' + userdata + ': ' + response.data.users[user][userdata] + "</li>";
output += '</ul>';
}
}
//Actualizamos el HTML del elemento con id="#response-container"
document.getElementById("response-container").innerHTML = output;
} else {
//response.success no es true
document.getElementById("response-container").innerHTML = 'No ha habido suerte: ' + response.data.message;
}
}
}
// Definimos como queremos realizar la comunicación
ajax_request.open( "GET", ajax_url, true );
//Enviamos la solictud con los parámetros que habíamos definido
ajax_request.send();
};
// Esperar a onload para poder acceder a los elementos del DOM
window.onload = function() {
// Obtener todos los botones que utilizamos para lanzar la solicitud Ajax
var userbutton = document.getElementsByTagName( "button" );
for (var i=0; i < userbutton.length; i++) {
// Para boton seleccionado, cuándo se haga click llamar a la funcion gedetails donde manjamos la solicitud ajax
userbutton[i].onclick = function() {
document.getElementById("response-container").innerHTML = "<p>Buscando...</p>";
// Obtener el valor de data-user, pasar a array si se necesita y ejecutar la funcion getdetails()
var id = this.getAttribute('data-user');
getdetails( id );
}
}
};
</script>
</head>
<body>
<p><button class="userdata" data-user="1">Dame los datos de la persona con ID = 1</button> - <button class="userdata" data-user='["1","2","3"]'>Dame los datos de las personas con ID = 1, ID = 2 e ID = 3.</button> - <button class="userdata" data-user="0">Ningún usuario</button></p>
<div id="response-container"></div>
</body>
</html>
Nota: A continuación puedes descargarte el ejemplo completo, incluido el script PHP. Antes de intentar ver el ejemplo en vivo, revisa el fichero PHP y cambia las credenciales de la base de datos de ejemplo que has tenido que crear previamente.Descargar el ejemplo completo
Referencias
- Objetos globales: JSON. Mozilla Developers Network.
- jаvascript Objets. w3schools.
- Web API Reference: XMLHttpRequest. Mozilla Developers Network.
Comentarios