¿De qué se trata JSONP?


Entiendo JSON, pero no JSONP. El documento de Wikipedia sobre JSON es (fue) el principal resultado de búsqueda para JSONP. Dice esto:

JSONP o "JSON with padding" es una extensión JSON en la que se especifica un prefijo como argumento de entrada de la llamada en sí.

¿Eh? ¿Qué llamada? Eso no tiene ningún sentido para mí. JSON es un formato de datos. No hay llamada.

El 2o resultado de la búsqueda es de un tipo llamado Remy , que escribe esto sobre JSONP:

JSONP es una inyección de etiquetas de script, que pasa la respuesta del servidor a una función especificada por el usuario.

Puedo entenderlo, pero todavía no tiene ningún sentido.


Entonces, ¿qué es JSONP? ¿Por qué se creó (qué problema resuelve)? ¿Y por qué lo usaría?


Addendum : Acabo de crear una nueva página para JSONP en Wikipedia; ahora tiene una descripción clara y completa de JSONP, basada en respuesta de jvenema.

Author: hippietrail, 2010-01-14

7 answers

En realidad no es demasiado complicado...

Diga que está en el dominio example.com, y desea realizar una solicitud al dominio example.net Para hacerlo, necesitas cruzar los límites de dominio, un no-no en la mayoría de browserland.

El único elemento que omite esta limitación son las etiquetas

Enter JSONP. Cuando realiza su solicitud a un servidor que está habilitado para JSONP, pasa un parámetro especial que informa al servidor un poco sobre su página. De esa manera, el servidor es capaz de envolver su respuesta de una manera que su página pueda manejar.

Por ejemplo, digamos que el servidor espera un parámetro llamado "callback" para habilitar sus capacidades JSONP. Entonces su solicitud se vería como:

http://www.example.net/sample.aspx?callback=mycallback

Sin JSONP, esto podría devolver algún objeto básico de JavaScript, como entonces:

{ foo: 'bar' }

Sin embargo, con JSONP, cuando el servidor recibe el parámetro "callback", envuelve el resultado un poco diferente, devolviendo algo como esto:

mycallback({ foo: 'bar' });

Como puede ver, ahora invocará el método que especificó. Por lo tanto, en su página, define la función de devolución de llamada:

mycallback = function(data){
  alert(data.foo);
};

Y ahora, cuando se cargue el script, será evaluado, y su función será ejecutada. Voila, solicitudes de dominios cruzados!

También vale la pena señalar el tema principal con JSONP: se pierde mucho control de la solicitud. Por ejemplo, no hay una forma" agradable " de recuperar los códigos de falla adecuados. Como resultado, terminas usando temporizadores para monitorear la solicitud, etc., lo cual siempre es un poco sospechoso. La propuesta para JSONRequest es una gran solución para permitir el scripting entre dominios, mantener la seguridad y permitir el control adecuado de la solicitud.

En estos días (2015), CORS es el enfoque recomendado vs.JSONRequest. JSONP está todavía útil para el soporte de navegadores más antiguos, pero dadas las implicaciones de seguridad, a menos que no tenga opción CORS es la mejor opción.

 1826
Author: jvenema,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-17 00:07:18

JSONP es realmente un truco simple para superar la política del mismo dominio de XMLHttpRequest. (Como usted sabe uno no puede enviar AJAX (XMLHttpRequest) solicitud a un dominio diferente.)

Así que - en lugar de usar XMLHttpRequesttenemos que usar script etiquetas HTML, las que normalmente se usan para cargar archivos js, para que js obtenga datos de otro dominio. Suena raro?

La cosa es - resulta que script las etiquetas se pueden usar de una manera similar para XMLHttpRequest ! Mira esto:

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data';

Terminarás con un segmento script que se ve así después de cargar los datos:

<script>
{['some string 1', 'some data', 'whatever data']}
</script>

Sin embargo, esto es un poco incómodo, porque tenemos que obtener este array desde la etiqueta script. Así que JSONP los creadores decidieron que esto funcionará mejor (y lo es):

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data?callback=my_callback';

Observe la función my_callback allí? So-cuando el servidor JSONP recibe su solicitud y encuentra la devolución de llamada parameter-en lugar de devolver un array js plano, devolverá esto:

my_callback({['some string 1', 'some data', 'whatever data']});

Vea dónde está el beneficio: ahora obtenemos una devolución de llamada automática (my_callback) que se activará una vez que obtengamos los datos.
Eso es todo lo que hay que saber sobre JSONP: es una devolución de llamada y etiquetas de script.

NOTA: estos son ejemplos simples de uso de JSONP, estos no son scripts listos para producción.

Ejemplo básico de JavaScript (simple Twitter feed usando JSONP)

<html>
    <head>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
        <script>
        function myCallback(dataWeGotViaJsonp){
            var text = '';
            var len = dataWeGotViaJsonp.length;
            for(var i=0;i<len;i++){
                twitterEntry = dataWeGotViaJsonp[i];
                text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
            }
            document.getElementById('twitterFeed').innerHTML = text;
        }
        </script>
        <script type="text/javascript" src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script>
    </body>
</html>

Ejemplo básico de jQuery (simple Twitter feed usando JSONP)

<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.ajax({
                    url: 'http://twitter.com/status/user_timeline/padraicb.json?count=10',
                    dataType: 'jsonp',
                    success: function(dataWeGotViaJsonp){
                        var text = '';
                        var len = dataWeGotViaJsonp.length;
                        for(var i=0;i<len;i++){
                            twitterEntry = dataWeGotViaJsonp[i];
                            text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
                        }
                        $('#twitterFeed').html(text);
                    }
                });
            })
        </script>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
    </body>
</html>


JSONP representa JSON con Relleno. (técnica muy mal llamada, ya que realmente no tiene nada que ver con lo que la mayoría de la gente pensaría como "relleno".)

 650
Author: ThatGuy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-15 07:57:19

JSONP funciona construyendo un elemento "script" (ya sea en marcado HTML o insertado en el DOM a través de JavaScript), que solicita a una ubicación de servicio de datos remota. La respuesta es un javascript cargado en su navegador con el nombre de la función predefinida junto con el parámetro que se pasa que son los datos JSON tht que se solicitan. Cuando se ejecuta el script, se llama a la función junto con los datos JSON, lo que permite que la página solicitante reciba y procese los datos.

Para Más Visita de Lectura: https://blogs.sap.com/2013/07/15/secret-behind-jsonp /

Fragmento de código del lado del cliente

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <title>AvLabz - CORS : The Secrets Behind JSONP </title>
     <meta charset="UTF-8" />
    </head>
    <body>
      <input type="text" id="username" placeholder="Enter Your Name"/>
      <button type="submit" onclick="sendRequest()"> Send Request to Server </button>
    <script>
    "use strict";
    //Construct the script tag at Runtime
    function requestServerCall(url) {
      var head = document.head;
      var script = document.createElement("script");

      script.setAttribute("src", url);
      head.appendChild(script);
      head.removeChild(script);
    }

    //Predefined callback function    
    function jsonpCallback(data) {
      alert(data.message); // Response data from the server
    }

    //Reference to the input field
    var username = document.getElementById("username");

    //Send Request to Server
    function sendRequest() {
      // Edit with your Web Service URL
      requestServerCall("http://localhost/PHP_Series/CORS/myService.php?callback=jsonpCallback&message="+username.value+"");
    }    

  </script>
   </body>
   </html>

Parte del código PHP del lado del servidor

<?php
    header("Content-Type: application/javascript");
    $callback = $_GET["callback"];
    $message = $_GET["message"]." you got a response from server yipeee!!!";
    $jsonResponse = "{\"message\":\"" . $message . "\"}";
    echo $callback . "(" . $jsonResponse . ")";
?>
 41
Author: Ajain Vivek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-22 14:20:30

Porque puede pedir al servidor que añada un prefijo al objeto JSON devuelto. E. g

function_prefix(json_object);

Para que el navegador eval "inline" la cadena JSON como expresión. Este truco hace posible que el servidor "inyecte" código javascript directamente en el navegador del cliente y esto evitando las restricciones de "mismo origen".

En otras palabras, puede tener intercambio de datos entre dominios.


Normalmente, XMLHttpRequest no permite dominios cruzados intercambio de datos directamente (uno necesita ir a través de un servidor en el mismo dominio) mientras que:

<script src="some_other_domain/some_data.js&prefix=function_prefix>` se puede acceder a los datos desde un dominio diferente al del origen.


También vale la pena señalar: a pesar de que el servidor debe ser considerado como "de confianza" antes de intentar ese tipo de "truco", los efectos secundarios de un posible cambio en el formato del objeto, etc. puede ser contenido. Si se utiliza un function_prefix (es decir, una función js adecuada) para recibir el objeto JSON, dicha función puede realizar comprobaciones antes de aceptar / seguir procesando los datos devueltos.

 37
Author: jldupont,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-13 09:22:49

JSONP es una gran distancia para sortear los errores de scripting entre dominios. Puede consumir un servicio JSONP exclusivamente con JS sin tener que implementar un proxy AJAX en el lado del servidor.

Puede utilizar el b1t.co servicio para ver cómo funciona. Este es un servicio JSONP gratuito que le permite reducir al mínimo sus URL. Aquí está la url a utilizar para el servicio:

Http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack]&url=[escapedUrlToMinify]

Para ejemplo de la llamada, http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

Volvería

whateverJavascriptName({"success":true,"url":"http://google.com","shortUrl":"http://b1t.co/54"});

Y por lo tanto cuando ese get se carga en su js como un src, automáticamente ejecutará whateverJavascriptName que debe implementar como su función de devolución de llamada:

function minifyResultsCallBack(data)
{
    document.getElementById("results").innerHTML = JSON.stringify(data);
}

Para hacer realmente la llamada JSONP, puede hacerlo de varias maneras (incluido el uso de jQuery), pero aquí hay un ejemplo puro de JS:

function minify(urlToMinify)
{
   url = escape(urlToMinify);
   var s = document.createElement('script');
   s.id = 'dynScript';
   s.type='text/javascript';
   s.src = "http://b1t.co/Site/api/External/MakeUrlWithGet?callback=resultsCallBack&url=" + url;
   document.getElementsByTagName('head')[0].appendChild(s);
}

Paso a paso ejemplo y un servicio web jsonp para practicar está disponible en: este post

 17
Author: dardawk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-05 15:20:37

Un ejemplo sencillo para el uso de JSONP.

Cliente.html

    <html>
    <head>
   </head>
     body>


    <input type="button" id="001" onclick=gO("getCompany") value="Company"  />
    <input type="button" id="002" onclick=gO("getPosition") value="Position"/>
    <h3>
    <div id="101">

    </div>
    </h3>

    <script type="text/javascript">

    var elem=document.getElementById("101");

    function gO(callback){

    script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'http://localhost/test/server.php?callback='+callback;
    elem.appendChild(script);
    elem.removeChild(script);


    }

    function getCompany(data){

    var message="The company you work for is "+data.company +"<img src='"+data.image+"'/   >";
    elem.innerHTML=message;
}

    function getPosition(data){
    var message="The position you are offered is "+data.position;
    elem.innerHTML=message;
    }
    </script>
    </body>
    </html>

Servidor.php

  <?php

    $callback=$_GET["callback"];
    echo $callback;

    if($callback=='getCompany')
    $response="({\"company\":\"Google\",\"image\":\"xyz.jpg\"})";

    else
    $response="({\"position\":\"Development Intern\"})";
    echo $response;

    ?>    
 10
Author: sarath joseph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-06 06:45:37

Antes de entender JSONP, necesita conocer el formato JSON y XML. Actualmente el formato de datos más utilizado en la web es XML, pero XML es muy complicado. Hace que los usuarios sean inconvenientes para procesar incrustados en páginas web.

Para hacer que JavaScript pueda intercambiar datos fácilmente, incluso como el programa de procesamiento de datos, utilizamos la redacción de acuerdo con los objetos JavaScript y desarrollamos un formato de intercambio de datos simple, que es JSON. JSON se puede utilizar como datos, o como un programa JavaScript.

JSON se puede incrustar directamente en JavaScript, usándolos puede ejecutar directamente cierto programa JSON, pero debido a restricciones de seguridad, el mecanismo de Sandbox del navegador deshabilita la ejecución de código JSON entre dominios.

Para que se pueda pasar JSON después de la ejecución, desarrollamos un JSONP. JSONP omite los límites de seguridad del navegador con la funcionalidad de devolución de llamada JavaScript y la etiqueta .

Así que en resumen explica qué es JSONP, qué problema resuelve (cuándo úsalo).

 9
Author: Marcus Thornton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-08 04:02:30