En este post te mostraré cómo hacer una petición JSON usando JavaScript y PHP como lenguaje de servidor.
Recuerda que ya hablamos sobre la definición de JSONP en otro post.
Nota: aquí está la demostración, y aquí el repositorio de GitHub.
Resumen
Vamos a hacer dos tipos de peticiones, una de ventas y otra de clientes. Al final el script de PHP dará un script de JavaScript que llama a una función.
Por ejemplo:
Ese es un script de JavaScript ficticio, creado por PHP. Como ves, solo se está llamando a la función especificada en la ruta, como veremos más adelante.
Lado del cliente
En el lado del cliente tenemos dos botones, uno para pedir ventas y otro para pedir clientes. Comenzamos definiendo la vista:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Ejemplo de JSONP con PHP</title>
</head>
<body>
<p>
No olvides abrir la consola con <kbd>F12</kbd>
<br>
<a target="_blank" href="//parzibyte.me/blog">By Parzibyte</a>
</p>
<button id="btnPedirClientes">Pedir clientes</button>
<button id="btnPedirVentas">Pedir ventas</button>
<script src="script.js"></script>
</body>
</html>
En la vista estamos cargando el script de JavaScript; no te confundas, ese es el script que se encarga de manejar la lógica del lado del cliente y de hacer las peticiones JSONP.
Ahora veamos el contenido del script de JavaScript:
// https://parzibyte.me/blog
// Definir los callbacks que serán llamados cuando la petición termine
const procesarClientes = clientes => {
console.log("Los clientes: ", clientes);
};
const procesarVentas = ventas => {
console.log("Las ventas: ", ventas);
};
// Obtener referencia a los botones
const btnPedirClientes = document.querySelector("#btnPedirClientes"),
btnPedirVentas = document.querySelector("#btnPedirVentas");
// Escuchar clicks de los botones
btnPedirClientes.addEventListener("click", () => {
// Comienza la petición JSONP
const script = document.createElement("script");
script.type = "text/javascript";
// Mira el callback, es procesarClientes
script.src = "./jsonp.php?callback=procesarClientes&peticion=clientes";
// Adjuntar y remover script, pues queremos que se cargue pero queremos removerlo al mismo tiempo
document.head.appendChild(script);
document.head.removeChild(script);
});
btnPedirVentas.addEventListener("click", () => {
// Comienza la petición JSONP
const script = document.createElement("script");
script.type = "text/javascript";
// Mira el callback, es procesarVentas
script.src = "./jsonp.php?callback=procesarVentas&peticion=ventas";
// Adjuntar y remover script, pues queremos que se cargue pero queremos removerlo al mismo tiempo
document.head.appendChild(script);
document.head.removeChild(script);
});
Se comienza definiendo ambos callbacks, que serán las funciones llamadas cuando la petición termine.
Dentro de esas funciones tenemos los datos traídos del servidor, y estamos listos para trabajar con ellos. En este caso solo imprimimos en la consola para ejemplificar y simplificar.
Ambos botones tienen un comportamiento similar, solo cambia la URL. En el primero es:
./jsonp.php?callback=procesarClientes&peticion=clientes
Y en el segundo es:
./jsonp.php?callback=procesarVentas&peticion=ventas
Como ves, estamos solicitando a un script de PHP, ya que la extensión del archivo no importa mientras regrese un encabezado indicando el tipo de contenido.
Para solicitar el script creamos un elemento de tipo script, lo adjuntamos para que se cargue y después lo removemos.
Recuerda que cuando el script haya cargado, el código que trae se evaluará.
Lado del servidor
En PHP el script es más sencillo, es importante mencionar que debemos poner el encabezado de tipo de dato en application/javascript:
<?php
// https://parzibyte.me/blog
if (!isset($_GET["callback"]) || !isset($_GET["peticion"])) {
exit("No hay parámetros");
}
// Obtener datos que el cliente necesita
$callback = $_GET["callback"];
$peticion = $_GET["peticion"];
// Los datos que vamos a regresar
$datos = array();
// Nota: los datos podrían ser objetos, arreglos, cadenas, etcétera
// Y podrían venir de una base de datos o de cualquier otro lugar
if ($peticion == "ventas") {
$datos = array("Una venta", "Otra venta");
} else if ($peticion == "clientes") {
$datos = array(
array(
"nombre" => "Luis",
"fecha_registro" => "2019-07-17",
),
array(
"nombre" => "María José",
"fecha_registro" => "2019-07-18",
),
);
} else {
exit("Petición incorrecta");
}
// Se supone que vamos a regresar un script de JS ;)
header("Content-type: application/javascript");
// Ahora codificamos los datos
$datosCodificados = json_encode($datos);
// Y escribimos literalmente código de JavaScript con PHP
$respuesta = "$callback($datosCodificados)";
// Salida: algo como
// procesarClientes([{"nombre":"Luis","fecha_registro":"2019-07-17"},{"nombre":"Mar\u00eda Jos\u00e9","fecha_registro":"2019-07-18"}])
// La escribimos
echo $respuesta;
// Listo, no hay que imprimir nada más
Leemos los valores de la URL para saber qué datos nos están pidiendo, y después de algunas comparaciones codificamos los datos con json_encode; creamos una cadena de respuesta y escribimos código de JavaScript con PHP.
La línea que dice $callback($datosCodificados)
va a evaluar a algo como lo siguiente:
procesarClientes([{“nombre”:”Luis”,”fecha_registro”:”2019-07-17″},{“nombre”:”Mar\u00eda Jos\u00e9″,”fecha_registro”:”2019-07-18″}])
Es como una concatenación.
La salida será la siguiente, variando los casos dependiendo del callback y petición:
Al evaluarse, se llamará a la función callback que ya definimos; dentro de esa función ya podemos procesar los datos.
Obviamente puedes regresar los datos de distintas fuentes, por ejemplo, de una base de datos de MySQL, PostgreSQL, SQL Server, MongoDB o SQLite.
También puedes poner parámetros adicionales en la URL, todo puede ser modificado a tu gusto.
Demostración
En el siguiente gif se puede ver cómo el callback de cada petición es invocado. Esto se logra solicitando un script de JavaScript que se evalúa dentro de nuestro código de JavaScript.
Puedes ver un ejemplo en vivo aquí, y acceder al repositorio en GitHub.