JSONP: Qué es, por qué se creó y por qué CORS lo reemplazó

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

JSONP: El arma secreta del frontend del pasado

\n

Imagina que eres un desarrollador web en 2010. Necesitas obtener datos de un servidor externo, por ejemplo, el pronóstico del tiempo o el tipo de cambio. Escribes una simple solicitud fetch, pero en la consola del navegador aparece un error rojo: «No 'Access-Control-Allow-Origin' header is present». ¿Te suena familiar?

\n

Esto es la Same-Origin Policy (política del mismo origen) que no permite que tu JavaScript salga del dominio local. Pero, ¿cómo funcionaban entonces los widgets del clima, los botones «Compartir» y los contadores de visitas? La respuesta es simple: usaban JSONP, un truco ingenioso del que hablaremos hoy.

\n

En este artículo responderemos a la popular pregunta de Stack Overflow: «What is JSONP, and why was it created?» — en lenguaje sencillo, con ejemplos de código y sin teoría innecesaria.

\n\n

1. El problema: ¿Por qué el navegador bloquea las solicitudes?

\n

El navegador es un paranoico. Protege al usuario de ataques XSS y robo de datos. La Same-Origin Policy permite que JavaScript lea respuestas solo del mismo dominio, protocolo y puerto.

\n

Ejemplo de bloqueo:

\n
// Este código provocará un error CORS\nfetch('https://api.distant-server.com/data')\n  .then(response => response.json())\n  .then(data => console.log(data));
\n

Pero hay una excepción: las etiquetas <script>. ¡El navegador carga scripts de cualquier dominio sin problemas! Es precisamente esta laguna la que aprovecha JSONP.

\n\n

2. La solución: JSONP — JSON con Padding

\n

JSONP (JSON with Padding) no es una tecnología ni un formato de datos, sino un patrón (parche) que evita la Same-Origin Policy mediante la etiqueta <script>.

\n

La idea es simple: en lugar de hacer una solicitud a través de XMLHttpRequest, creamos dinámicamente un elemento <script>, especificamos la URL del servidor, y el servidor devuelve no JSON, sino código JavaScript que llama a nuestra función con los datos.

\n\n

Cómo se ve un JSON normal:

\n
// Respuesta del servidor (JSON normal)\n{"name": "PythonLib", "topic": "JSONP"}
\n\n

Cómo se ve JSONP:

\n
// Respuesta del servidor (JSONP)\nmyCallback({"name": "PythonLib", "topic": "JSONP"});
\n

La diferencia es enorme: en el segundo caso, el servidor envuelve los datos en una llamada a la función myCallback. Eso es precisamente el padding (envoltura).

\n\n

3. Práctica: Escribiendo una solicitud JSONP manualmente

\n

Implementemos un cliente JSONP en JavaScript puro. Esto ayudará a entender la magia.

\n\n
function jsonp(url, callbackName) {\n  // 1. Creamos una función global (callback)\n  window[callbackName] = function(data) {\n    console.log('Datos recibidos:', data);\n    delete window[callbackName]; // Limpiamos\n    document.body.removeChild(script);\n  };\n\n  // 2. Creamos la etiqueta script\n  const script = document.createElement('script');\n  script.src = `${url}?callback=${callbackName}`; // Pasamos el nombre del callback\n  script.onerror = function() {\n    console.error('Error al cargar JSONP');\n    delete window[callbackName];\n    document.body.removeChild(script);\n  };\n\n  // 3. Lo agregamos al DOM — el navegador carga y ejecuta el script inmediatamente\n  document.body.appendChild(script);\n}\n\n// Uso:\njsonp('https://api.example.com/data', 'handleData');
\n

Cómo funciona paso a paso:

\n
    \n
  • Creamos una función global handleData.
  • \n
  • Agregamos la etiqueta <script> con la URL del servidor. En la URL pasamos el parámetro ?callback=handleData.
  • \n
  • El servidor que soporta JSONP ve el parámetro callback y devuelve no JSON, sino JavaScript: handleData({...}).
  • \n
  • El navegador ejecuta este script, se llama a nuestra función y obtenemos los datos.
  • \n
\n\n

4. ¿Por qué JSONP es malo? (Desventajas)

\n

Si pensaste: «Genial, lo usaré en todas partes»

Blogs

Book Recommendations