2010-03-04 6 views
28

He estado jugando un poco a llamar a mi servicio que está en un dominio diferente usando jQuery. La llamada al servicio se realiza con éxito (mi punto de depuración se desconecta) y se devuelve la respuesta correcta (husmeo el tráfico).La función de éxito de Jquery no está activada con JSONP

Mi problema es principalmente que las devoluciones de llamadas de éxito y fracaso no se activan. He leído algunos other posts en SO que indican que el evento de error no se dispara cuando se usa JSONP. Es ese el caso con el evento de éxito (tal vez porque se supone que estoy proporcionando mi propia función de devolución de llamada), también, o hay una manera de activar mi devolución de llamada exitosa. Gracias por adelantado.

$.ajax({ 
    type: "GET", 
    url: urlOnDiffDomain, 
    async: false, 
    cache: false, 
    dataType: 'jsonp', 
    data: {}, 
    success: function(data, textStatus) { 
    alert('success...'); 
    }, 
    error: function(xhr, ajaxOptions, thrownError) { 
    alert('failed....'); 
    } 
}); 
+0

¿Has trabajado con esto en un depurador? Después de la llamada, ¿puede decir si jQuery ha agregado una función global con un nombre como "jsonpNNN" (donde NNN es un número)? – Pointy

+0

Sí, jquery ha agregado una función global jsonPXXXX –

Respuesta

19

Alright. En caso de que alguien necesite saberlo en el futuro ... En retrospectiva, la solución probablemente debería haber sido más obvia de lo que era, pero debe tener la respuesta web escrita directamente en la secuencia de respuesta . Simplemente devolver una cadena de JSON no lo hace, necesita que alguien lo construya y lo vuelva a transmitir. El código en mi publicación original funcionará bien si realmente lo haces.

Ejemplo de código de servicio:

public void DoWork() 
{ 
    //it will work without this, but just to be safe 
    HttpContext.Current.Response.ContentType = "application/json"; 
    string qs = HttpContext.Current.Request.QueryString["callback"]; 
    HttpContext.Current.Response.Write(qs + "([{ \"x\": 10, \"y\": 15}])"); 
} 

Sólo por el hecho de ser explícita, este es el código del lado del cliente.

function localDemo(){ 
    $.getJSON("http://someOtherDomain.com/Service1.svc/DoWork?callback=?", 
    function(data){ 
     $.each(data, function(i,item){    
     alert(item.x); 
     }); 
    }); 
} 

Si hay una mejor manera de hacerlo, soy todo oídos. Para todos los demás, sé que hay algún concepto de soporte nativo en WCF 4.0 para JSONP. Además, es posible que desee hacer un poco de checking por razones de seguridad, aunque no he investigado mucho.

+0

La manera más fácil de hacer un servicio JSONP en .NET es usar un controlador HTTP, luego no hay marcas de página para suprimir, solo escribe en la secuencia de respuesta. – Guffa

+0

Por curiosidad: ¿Cómo "devolvió" la cadena cuando no la escribió en el flujo de respuesta? – Guffa

+0

Acuerdo Guffa. Tampoco ayuda que sea complicado eliminar el contenedor JSON predeterminado que le ofrece WCF. Puede evitarlo, pero es solo una cosa más a tener en cuenta. R: Haciendo ingenuamente una devolución de "cosas"; –

0

Trate

$.getJSON(urlOnDiffDomain, function(data, textStatus){ 
    alert('success...'); 
}); 

Obras para mí, Normalamente. Necesita agregar & callback =? a urlOnDiffDomain, donde jQuery reemplaza automáticamente la devolución de llamada utilizada en JSONP.

La respuesta de error no se dispara, pero se puede utilizar el mundial $ .ajaxError, como este

$('.somenode').ajaxError(function(e, xhr, settings, exception) { 
    alert('failed'); 
}); 
+1

Con el servicio devolviendo la cadena de la misma forma que indiqué en mi primer comentario anterior ... si termino mi URL con & callback = ?, obtengo un http 403. Si termino con ? callback = ?, llego al servicio, pero mi evento de éxito aún no se ha activado: -? (Jquery crea la función JSONPXXXX) –

13

El método de devolución de llamada success se llama cuando el servidor responde. El método $.ajax establece una función que maneja la respuesta llamando al método de devolución de llamada success.

La razón más probable por la que no se llama al método success es que la respuesta del servidor no es correcta. El método $.ajax envía un valor en la cadena de consulta callback que el servidor debe usar como nombre de función en la respuesta JSONP. Si el servidor utiliza un nombre diferente, nunca se llama a la función que el método $.ajax ha configurado.

Si el servidor no puede usar el valor en la cadena de consulta callback para establecer el nombre de la función en la respuesta, puede especificar qué nombre de función debe esperar el método $.ajax del servidor. Agregue la propiedad jsonpCallback al objeto de opción y establezca el valor para el nombre de la función que usa el servidor en la respuesta.

Si por ejemplo el método $.ajax está enviando una solicitud al servidor utilizando la dirección URL http://service.mydomain.com/getdata?callback=jsonp12345, el servidor debe responder con algo parecido a:

jsonp12345({...}); 

Si el servidor ignora la cadena callback consulta, y en cambio responde con algo como:

mycallback({...}); 

a continuación, tendrá que reemplazar el nombre de la función mediante la adición de una propiedad a las opciones de objeto:

$.ajax({ 
    url: urlOnDiffDomain, 
    dataType: 'jsonp', 
    data: {}, 
    success: function(data, textStatus) { 
    alert('success...'); 
    }, 
    jsonpCallback: 'mycallback' 
}); 
+0

He cambiado el valor devuelto por mi servicio. Ahora se ve así: cadena qs = HttpContext.Current.Request.QueryString ["callback"]; return qs + "({'d': 's'})"; Dado el siguiente código del lado del cliente: var url = 'http: //some.other.domain/service/serviceName.svc/param1/1/param2/2'; $ .ajax ({ url: url, tipoDatos: 'jsonp', datos: {}, jsonpCallback: 'MyCallback', de éxito: function (datos, textStatus) { de alerta (datos); } }) El contenido de la respuesta se ve así: "jsonp1267721964115 ({'d': 's'})" Parece que está conectando una función de devolución de llamada a pesar de la propiedad? –

+0

Ugh. Perdón por ese formato –

+0

@rhythmaddict: ¿Qué versión de jQuery estás usando? Necesita la versión 1.4 o posterior para la propiedad jsonpCallback que se utilizará. Sin embargo, cuando cambió el código del servidor para usar correctamente la cadena de consulta de devolución de llamada, no necesita usar la propiedad jsonpCallback. – Guffa

0

Esta no es una respuesta completa a su pregunta, pero creo que alguien que pasa por gustaría saber esto:

Cuando tratas con JSONP from WCF REST tratan de utilizar:

[JavascriptCallbackBehavior(UrlParameterName = "$callback")]

de su implementación del servicio; esto debería darte JSONP out-of-the-box.

0
$.ajax({ 
       url:' <?php echo URL::site('ajax/editing?action=artistSeracher') ?>', 
       dataType: "json", 
       data: { 
        featureClass: "P", 
        style: "full", 
        maxRows: 12, 
        artist: request.term 
       }, 
       success: function(data) { 
        response($.map(data, function(item) { 
         return { 
          label: item.artist, 
          value: item.artist, 
          id: item.id 
         } 
        })); 
       }, 
       error: function (xhr, ajaxOptions, thrownError) { 
        alert(xhr.status); 
        alert(thrownError); 
        } 
      }); 
+6

Al publicar una respuesta, no solo proporcione el código. Por favor explique qué hará su código o cómo es diferente al ejemplo del póster original.La respuesta funcionará mejor si puede explicarla al cartel original para que entiendan lo que está haciendo. –

Cuestiones relacionadas