Ejemplo básico de uso de .ajax () con JSONP?

187

¿Podría alguien ayudarme a resolver cómo comenzar con JSONP?

Código:

$('document').ready(function() {
    var pm_url = 'http://twitter.com/status';
    pm_url += '/user_timeline/stephenfry.json';
    pm_url += '?count=10&callback=photos';
    var photos = function (data) {
     alert(data);
    };
    $.ajax({
        url: pm_url,
        dataType: 'jsonp',
        jsonpCallback: 'photos',
        jsonp: false,
    });
});

Violín: http://jsfiddle.net/R7EPt/6/

Debería generar una alerta, por lo que puedo deducir de la documentación: no es (pero tampoco produce ningún error).

Gracias.

Simón
fuente
$ .ajax ({url: pm_url, tipo de datos: 'jsonp', jsonpCallback: fotos, jsonp: falso,}); Había ingresado fotos como una cadena.
wOlVeRiNe

Respuestas:

388

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

Entonces, en lugar de usar XMLHttpRequest , tenemos que usar etiquetas HTMLl de script , las que usualmente usas para cargar archivos JS, para que JS obtenga datos de otro dominio. ¿Suena raro?

La cosa es que resulta que las etiquetas de script se pueden usar de manera similar a XMLHttpRequest . Mira esto:

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

Terminará con un segmento de 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 buscar esta matriz desde la etiqueta del script . Entonces, los creadores de JSONP 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";

¿ Notan la función my_callback allí? Entonces, cuando el servidor JSONP recibe su solicitud y encuentra el parámetro de devolución de llamada, en lugar de devolver una matriz JS simple, 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 del uso de JSONP, estos no son scripts listos para producción.

Demostración de JavaScript RAW (feed de Twitter simple 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 (feed de Twitter simple 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 significa JSON con relleno . (técnica muy mal nombrada, ya que realmente no tiene nada que ver con lo que la mayoría de la gente pensaría como "relleno").

Ese tipo
fuente
3
Esta respuesta ahora está algo desactualizada porque los navegadores ahora admiten Access-Control-Allow-Originencabezados que permiten realizar llamadas regulares de Ajax a algunos dominios de origen cruzado.
jfriend00 13/03/2015
Tenga en cuenta que no puede hacer un POST de formulario con JSONP. Más información aquí: markhneedham.com/blog/2009/08/27/…
thdoan
44
¿Qué debe tener en cuenta si desea que estos scripts estén listos para producción?
invitado
1
¡Guau, esto es realmente útil! Finalmente llego a saber qué es exactamente JSONP y cómo funciona.
Jerry Liu
146

Hay una manera aún más fácil de trabajar con JSONP usando jQuery

$.getJSON("http://example.com/something.json?callback=?", function(result){
   //response data are now in the result variable
   alert(result);
});

El ?final de la URL le dice a jQuery que es una solicitud JSONP en lugar de JSON. jQuery registra y llama a la función de devolución de llamada automáticamente.

Para obtener más detalles, consulte la documentación de jQuery.getJSON .

Petr Peller
fuente
2
@PetrPeller, parece genial, pero no creo que sea un producto. ¿Puedes ver esto alguna vez? JSFiddle No alerta datos. Tal vez me perdí algo
tika
La respuesta @xDNP JSONP debe ser compatible con el servidor. Su servidor no parece admitirlo , ya que no puedo ver ninguna devolución de llamada adicional aquí: mylivecanvas.com/api/… . También debe usarlo, &callback=?ya que no es el primer parámetro en su caso.
Petr Peller
1
@PetrPeller Estoy muy interesado en su solución. Pero eso no funciona en mí. No quiero publicar una nueva pregunta, pero no me ayuda. ¿Qué significa que no parece ser compatible con el servidor ? ¿Qué tengo que hacer? ¿Y me puede dar una URL completa que funcione para mi servidor? Te estaría agradecido. ¿Necesito alguna configuración de servidor?
tika
3
¿Qué hace la última edición, "Por favor, no uses más jQuery!" ¿media?
ParkCheolu
1
¡Ahora es 2018, y no estoy seguro de qué se supone que se usará en 2017!
Vasily Hall
28

En respuesta al OP, hay dos problemas con su código: necesita establecer jsonp = 'callback', y agregar una función de devolución de llamada en una variable como lo hizo no parece funcionar.

Actualización: cuando escribí esto, la API de Twitter estaba abierta, pero la cambiaron y ahora requiere autenticación. Cambié el segundo ejemplo a un ejemplo de trabajo (2014Q1), pero ahora estoy usando github.

Esto ya no funciona: como ejercicio, vea si puede reemplazarlo con la API de Github:

$('document').ready(function() {
    var pm_url = 'http://twitter.com/status';
    pm_url += '/user_timeline/stephenfry.json';
    pm_url += '?count=10&callback=photos';
    $.ajax({
        url: pm_url,
        dataType: 'jsonp',
        jsonpCallback: 'photos',
        jsonp: 'callback',
    });
});
function photos (data) {
    alert(data);
    console.log(data);
};

aunque alertar () una matriz como esa realmente no funciona bien ... La pestaña "Red" en Firebug te mostrará el JSON correctamente. Otro truco útil es hacer

alert(JSON.stringify(data));

También puede usar el método jQuery.getJSON . Aquí hay un ejemplo completo de HTML que obtiene una lista de "gists" de github. De esta manera crea una función de devolución de llamada nombrada al azar para usted, esa es la "devolución de llamada =?" Final en la url.

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>JQuery (cross-domain) JSONP Twitter example</title>
        <script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.getJSON('https://api.github.com/gists?callback=?', function(response){
                    $.each(response.data, function(i, gist){
                        $('#gists').append('<li>' + gist.user.login + " (<a href='" + gist.html_url + "'>" + 
                            (gist.description == "" ? "undescribed" : gist.description) + '</a>)</li>');
                    });
                });
            });
        </script>
    </head>
    <body>
        <ul id="gists"></ul>
    </body>
</html>
PapaFreud
fuente
2
Tienes razón, ya no funciona. Twitter cambió su API.
PapaFreud
3
<!DOCTYPE html>
<html>
<head>
<style>img{ height: 100px; float: left; }</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<title>An JSONP example </title>
</head>
<body>
<!-- DIV FOR SHOWING IMAGES -->
<div id="images">
</div>
<!-- SCRIPT FOR GETTING IMAGES FROM FLICKER.COM USING JSONP -->
<script>
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
  format: "json"
},
//RETURNED RESPONSE DATA IS LOOPED AND ONLY IMAGE IS APPENDED TO IMAGE DIV
function(data) {
  $.each(data.items, function(i,item){
  $("<img/>").attr("src", item.media.m).appendTo("#images");

 });
});</script>
</body>
</html> 

El código anterior ayuda a obtener imágenes de la API Flicker. Esto usa el método GET para obtener imágenes usando JSONP. Se puede encontrar en detalle aquí.

Ganesh Babu
fuente