2012-04-17 31 views
17

Tengo problemas para entender los detalles de cómo funciona una solicitud jsonp. He leído varias fuentes, incluida la wiki en jsonp, y todavía estoy muy confundido sobre cómo la devolución de llamada realmente retiene la función devuelta por el servidor cuando se realiza una llamada jsonp. Por ejemplo, en el wiki, la fuente de la solicitud se establece como:Confundido en cómo funciona una solicitud JSONP

src="http://server2.example.com/RetrieveUser?UserId=1234&jsonp=parseResponse" 

¿Qué hace exactamente jsonp = parseResponse realmente hacen/quiere decir ?? Luego continúan para decir que la carga útil es:

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7}); 

¿Cómo funciona esto? Estoy confundido sobre toda la funcionalidad de devolución de llamada. El nombre de la función parseResponse se pasa al servidor y de alguna manera los datos devueltos se convierten en parámetros para esta función? ¿Puede alguien explicar claramente cómo se recuperan/utilizan los datos de una solicitud jsonp?

+0

posible duplicado de [Explique JSONP] (http://stackoverflow.com/questions/2067472/please-explain-jsonp) – Jon

Respuesta

40

La devolución de llamada es una función USTED 'VE definido en tu propio código. El servidor jsonp ajustará su respuesta con una llamada de función llamada igual que su función de devolución de llamada especificada.

¿Qué ocurre lo siguiente:

1) Su código crea la solicitud JSONP, lo que se traduce en una nueva <script> bloque que tiene este aspecto:

<script src="http://server2.example.com/RetrieveUser?UserId=1234&jsonp=parseResponse"></script> 

2) Esa nueva etiqueta script es ejecutado por su navegador, lo que da como resultado una solicitud al servidor JSONP.Responde con

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7}); 

3) Dado que esta petición procedía de una etiqueta de script, es casi exactamente lo mismo que si hubiera colocado literalmente

<script> 
    parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7}); 
</script> 

en su página.

4) Ahora que esta nueva secuencia de comandos se ha cargado desde el servidor remoto, ahora se ejecutará, y lo único que hará es llamar a la función, parseResponse(), pasando los datos JSON como el único parámetro de la llamada a la función .

Así que otra parte de su código, tendríamos:

function parseResponse(data) { 
    alert(data.Name); // outputs 'Foo' 
} 

Básicamente, JSONP es una manera de eludir la política de seguridad de la escritura del mismo origen del navegador, por tener un servidor de 3 ª parte inyectar una llamada de función directamente en tu página. Tenga en cuenta que esto es por diseño altamente inseguro. Depende de que el servicio remoto sea honorable y no tenga una intención maliciosa. Nada impide que un mal servicio devuelva un código JS que le roba sus credenciales de banca/facebook/lo que sea. por ejemplo, la respuesta JSONP podría haber sido

internalUseOnlyFunction('deleteHarddrive'); 

en lugar de parseReponse (...). Si el sitio remoto conoce la estructura de su código, puede realizar operaciones arbitrarias con ese código, porque ha abierto la puerta de entrada de par en par para permitir que ese sitio haga lo que quiera.

+8

No llegaría tan lejos como 'deleteHardDrive' (JavaScript no puede hacer eso desde el navegador) pero definitivamente vale la pena señalar que esto puede ser peligroso. – hitautodestruct

+1

¡Gran explicación! – FloatingRock

1

Editar: Como dijo Jon, hay una manera mejor explicación para él here.

JSONP usa etiquetas de script para realizar solicitudes de origen cruzadas. Como una etiqueta de script se usa para incluir scripts, el servidor debe devolver JavaScript válido. La forma en que le damos el JavaScript al cliente es a través de una llamada a función. Le dice al servidor a qué función quiere que llame la secuencia de comandos, y luego crea esa función localmente. Cuando la secuencia de comandos termine de cargarse, se invocará su función con los datos como parámetro.

Así que si usted hizo una petición JSONP en la URL que usted ha mencionado, y volvió la carga útil que usted ha mencionado, se llega a sus datos al hacer esto:

function parseResponse(data) { 
    console.log("JSONP request complete", data); 
} 
+0

¿Cómo los datos devueltos mágicamente se convierten en el parámetro para la función parseRepsonse? –

+0

@JohnBaum porque el servidor crea el código JS que se llamará? –

0

se pasa el nombre parseResponse función al servidor y de alguna manera los datos devueltos se convierte en parámetros de esta función

parece que se acaba de explicar por sí mismo, jsonp=parseResponse es cómo esta aplicación pone a la función de devolución de llamada, por lo que devuelve una func ción con sus datos JSON en ella, que se parece a

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7}); 

que se llama cuando se ha cargado y se controla mediante una función en sus JS como:

function parseResponse(data){ 
    console.log(data); 
} 
Cuestiones relacionadas