javascript

Ejemplo de JSONP con PHP

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:

JSONP y PHP: script de respuesta

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:

JSONP y PHP: script de respuesta

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.

Callback de JavaScript ejecutándose con JSONP

Puedes ver un ejemplo en vivo aquí, y acceder al repositorio en GitHub.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

1 semana hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

2 semanas hace

Esta web usa cookies.