Pages

martes, agosto 07, 2012

JSONP - Cross Domain AJAX, Ejemplo con jQuery y PHP

Si ud. como yo, es un pobre programador que ha intentado hacer alguna aplicacion para telefonos Android y tuvo la peregrina idea de hacer que el telefono tenga la logica de su lado y se comunique via Ajax con su servidor... Entonces esta entrada se la dedico desde el fondo de mi corazón.

Después de mucho deambular leyendo un montón de incoherencias llegué a un post que me mostró la luz. http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/
De ahí en mas avancé y aqui van mis conclusiones.

1) llamada ajax en javascript con jQuery:

$.ajax({
 dataType: "jsonp",
 url: "http://algunotrodominio.com/unscript.php",
 data: "parametro1=valor1&parametro2=valor2",
 type: GET,
 crossDomain: true,
 jsonpCallback:'jpCallback',
 success: function(jsondata) {   
  datos = jsondata[0].respuesta.datos;
  otros = jsondata[0].respuesta.otracosa;
  (hacer algo con todo esto.)
 },
 error: function (jqXHR, textStatus, errorThrown) {
   (haceralgo)
 }
});

jpCallback(jsondata){
  (pueden ejecutar alguna validación previa con los datos,
 o no hacer absolutamente nada.)
} 

2) unscript.php :
<?php

$json = '{ "respuesta": {
   "datos": [ 
              {"codigo": 1, "dato": "algo1"},
              {"codigo": 2, "dato": "algo2"}
            ],
   "otracosa":"undatomasadevolver"  
   }   
}';
  
echo 'jpCallback(['.$json.'])';
?> 

Y eso es todo. Si no lo captaron: al $.ajax() de jQuery modifican el dataType a "jsonp", esto solo ya habilita a hacer una llamada cross domain. pero hay un parametro mas crossDomain : true. Sin esto tambien funciona. jsonpCallback : 'nombredefuncioncallback' Al decir que esto es "jsonp" jQuery agrega 2 parametros a la cadena de datos que se envian por ejemplo:

http://algunotrodominio.com/unscript.php?callback=jQuery17206061169685839634_1344380380503&parametro1=valor1&parametro2=valor2&_=1344380387364

si en cambio agregamos el parametro jsonpCallback : 'funcioncallback' entonces la llamada se parecera a esto:

http://algunotrodominio.com/unscript.php?callback=funcioncallback&parametro1=valor1&parametro2=valor2&_=1344380387364

Como sea lo importante es que la devolucion del script PHP debe ser el nombre de la funcion callback y como parametro de la funcion el JSON que quiero devolver. jQuery ejecuta entonces la funcion callback y luego al success: envia solo el objeto JSON. En el ejemplo muestro como acceder a los distintos componentes.

Espero que les sea útil.

20 comentarios:

  1. Gracias, muy bien explicado.

    ResponderEliminar
    Respuestas
    1. De nada, gracias por pasarte por aqui.

      Eliminar
  2. El último parrafo explica todo...GRACIAS.

    ResponderEliminar
    Respuestas
    1. De nada, gracias por pasar por aqui.

      Eliminar
  3. Hola oye amigo me sirvió muchísimo tu explicación, pero tengo un problema cuando lo envío datos por POST.

    tengo el inicio de código en php así
    <?php
    if( isset( $_POST["datos"] ) ){
    //has algo
    $json = '{
    "respuesta": {
    "fn": "yeahhh :)"
    }
    }';
    echo 'jpCallback(['.$json.'])';
    }

    Realizando el envío por GET funciona de maravilla, pero cuando lo envío por post no funciona, que estará pasando?

    ResponderEliminar
    Respuestas
    1. Si bien me estoy dando cuenta que el ejemplo lo escribi con POST en la llamada por ajax, lo cierto es que solo funciona por GET, no funciona por POST. Ya corrijo el ejemplo. Gracias por el comentario.

      Eliminar
    2. Una cosa mas, el ejemplo andaba como estaba, pero los parametros si o si los envia por GET al poner en datatype jsonp. Es decir del lado PHP no te va a llegar nunca una variable POST.

      Eliminar
  4. excelente!!!
    felicitaciones

    ResponderEliminar
  5. Esta muy bien explicado,lo probare gracias por tu aporte aunque mi idea es usarlo desde una app mobile tipo rest service crees que funcione? gracias de antemano por tu respuesta

    ResponderEliminar
    Respuestas
    1. Disculpá mi ignorancia, ¿que es un rest service?.

      Eliminar
    2. La Transferencia de Estado Representacional (Representational State Transfer) o REST es una técnica de arquitectura software , osea es una arquitectura orientada a servicios

      Eliminar
    3. Grazie estimado Jerson. Me puse a leer un poco. Me fascina que la gente le viva inventando nombres y siglas a técnicas viejas como el mundo. No se tome a mal el comentario que no es contra ud.!

      Eliminar
  6. Hola buenas noches, muchas gracias me sirvió muchísimo tu ejemplo
    Solo tengo un inconveniente, al momento de hacer dos instancias del $.ajax llamando a dos archivos distintos.

    Teniendo $.ajax A y $.ajax B
    Me genera error en A y B corre normal,
    Al dejar comentarizado B, A funciona normal.

    El error es por algún motivo que conozcas?
    O en tu caso funcionan múltiples instancias en el mismo evento sin problema?

    ResponderEliminar
  7. Me auto contesto, por si a alguien le llegase a suceder.
    La solución a mi dilema fue poner una función de callback distinta para cada caso

    jpCallbackT caso A
    jpCallback caso B

    En el archivo del js y del php respectivamente.

    De nuevo muchas gracias por tu aporte, no sabes cuanto me ha servido.

    ResponderEliminar
    Respuestas
    1. Gracias por el ejemplo y la autorespuesta!. De cualquier forma, no es necesario ni obligatorio crear un callback. De hecho, podes tomar el nombre que sugiere por defecto jQuery, en el caso de que no definas uno propio, del array $_GET y devolverlo con el json en el interior. Al no encontrar de vuelta el callback pasa derecho al success. Saludos.

      Eliminar
  8. Excelente, me ayudó como no tienes idea, muchas gracias !

    ResponderEliminar
    Respuestas
    1. Me alegro mucho. Quien quiera que seas.

      Eliminar
  9. Hola, una pregunta, como podria hacer un login utilizando jsonp? digamos que en local tengo el html con el formulario para user y pass, y en el servidor el archivo php que lo comprueba en mysql, como tendria que hacerlo? como envio las variables del formulario y las devuelvo al html?
    disculpa es que no tengo muchos conocimientos.
    Saludos

    ResponderEliminar
    Respuestas
    1. Gracias por pasar por aqui. No veo cual sería el impedimento para que lo hagas con JSONP, sin embargo entiendo que tu pregunta es mucho mas amplia y seguro vas a encontrar 10 millones de ejemplos de como hacer un login con ajax. Suerte!.

      Eliminar