from - jsonp jquery
¿Alguien puede explicar qué es JSONP, en términos simples? (4)
Prefacio:
Esta respuesta tiene más de seis años. Si bien los conceptos y la aplicación de JSONP no han cambiado (es decir, los detalles de la respuesta siguen siendo válidos), debe usar CORS siempre que sea posible (es decir, su server o API admite, y el soporte del navegador es adecuado), como JSONP Tiene riesgos de seguridad inherentes .
JSONP ( JSON con relleno ) es un método comúnmente utilizado para omitir las políticas de dominios cruzados en los navegadores web. (No está permitido realizar solicitudes AJAX a una página web que se percibe como que se encuentra en un servidor diferente por el navegador).
JSON y JSONP se comportan de manera diferente en el cliente y el servidor. Las solicitudes JSONP no se envían utilizando el XMLHTTPRequest
y los métodos de navegador asociados. En su lugar, se crea una etiqueta <script>
, cuyo origen se establece en la URL de destino. Esta etiqueta de script se agrega al DOM (normalmente dentro del elemento <head>
).
Solicitud JSON:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// success
};
};
xhr.open("GET", "somewhere.php", true);
xhr.send();
Solicitud JSONP:
var tag = document.createElement("script");
tag.src = ''somewhere_else.php?callback=foo'';
document.getElementsByTagName("head")[0].appendChild(tag);
La diferencia entre una respuesta JSON y una respuesta JSONP es que el objeto de respuesta JSONP se pasa como un argumento a una función de devolución de llamada.
JSON:
{ "bar": "baz" }
JSONP:
foo( { "bar": "baz" } );
Esta es la razón por la que ve solicitudes JSONP que contienen el parámetro de callback
, de modo que el servidor sepa el nombre de la función para envolver la respuesta.
Esta función debe existir en el ámbito global en el momento en que el navegador evalúa la etiqueta <script>
(una vez que la solicitud se ha completado).
Otra diferencia a tener en cuenta entre el manejo de una respuesta JSON y una respuesta JSONP es que cualquier error de análisis en una respuesta JSON podría detectarse envolviendo el intento de evaluar el texto de respuesta en una declaración try / catch. Debido a la naturaleza de una respuesta JSONP, los errores de análisis en la respuesta causarán un error de análisis de JavaScript que no se puede capturar.
Ambos formatos pueden implementar errores de tiempo de espera estableciendo un tiempo de espera antes de iniciar la solicitud y borrando el tiempo de espera en el controlador de respuesta.
La utilidad de usar jQuery para realizar solicitudes JSONP, es que jQuery hace todo el trabajo por usted en segundo plano.
Por defecto, jQuery requiere que incluya &callback=?
en la URL de su solicitud de AJAX. jQuery tomará la función de success
que especifique, le asignará un nombre único y lo publicará en el ámbito global. ¿Entonces reemplazará el signo de interrogación ?
en &callback=?
Con el nombre que tiene asignado.
Implementaciones JSON / JSONP comparables
Lo siguiente asume un objeto de respuesta { "bar" : "baz" }
JSON:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("output").innerHTML = eval(''('' + this.responseText + '')'').bar;
};
};
xhr.open("GET", "somewhere.php", true);
xhr.send();
JSONP:
function foo(response) {
document.getElementById("output").innerHTML = response.bar;
};
var tag = document.createElement("script");
tag.src = ''somewhere_else.php?callback=foo'';
document.getElementsByTagName("head")[0].appendChild(tag);
Esta pregunta ya tiene una respuesta aquí:
- ¿De qué se trata JSONP? 7 respuestas
Sé que JSONP
es JSON
con relleno.
Entiendo qué es JSON y cómo usarlo con jQuery.getJSON()
. Sin embargo, no entiendo el concepto de callback
de callback
al introducir JSONP.
¿Puede alguien explicarme cómo funciona esto?
Digamos que tenías una URL que te dio datos JSON como:
{''field'': ''value''}
... y tenías una URL similar, excepto que usaba JSONP, a la que pasaste el nombre de la función de devolución de llamada ''myCallback'' (generalmente se hace dándole un parámetro de consulta llamado ''devolución de llamada'', por ejemplo, http://example.com/dataSource?callback=myCallback
). Entonces volvería:
myCallback({''field'':''value''})
... que no es solo un objeto, sino que en realidad es un código que puede ejecutarse. Entonces, si define una función en otra parte de su página llamada myFunction
y ejecuta este script, se llamará con los datos de la URL.
Lo bueno de esto es que puede crear una etiqueta de script y usar su URL (completa con el parámetro de callback
) como el atributo src
, y el navegador lo ejecutará. Eso significa que puede sortear la política de seguridad de "mismo origen" (porque los navegadores le permiten ejecutar etiquetas de script desde fuentes distintas al dominio de la página).
Esto es lo que hace jQuery cuando realiza una solicitud ajax (usando .ajax
con ''jsonp'' como valor para la propiedad dataType
). P.ej
$.ajax({
url: ''http://example.com/datasource'',
dataType: ''jsonp'',
success: function(data) {
// your code to handle data here
}
});
Aquí, jQuery se encarga del nombre de la función de devolución de llamada y del parámetro de consulta, lo que hace que la API sea idéntica a otras llamadas ajax. Pero a diferencia de otros tipos de solicitudes ajax, como se mencionó, no está restringido a obtener datos del mismo origen que su página.
He encontrado un artículo útil que también explica el tema con bastante claridad y un lenguaje sencillo. Enlace es JSONP
Algunos de los puntos a destacar son:
- JSONP es anterior a CORS.
- Es una forma pseudo-estándar para recuperar datos de un dominio diferente,
- Tiene funciones CORS limitadas (solo método GET)
El trabajo es el siguiente:
-
<script src="url?callback=function_name">
está incluido en el código html - Cuando se ejecuta el paso 1, detecta una función con el mismo nombre de función (como se indica en el parámetro url) como respuesta.
- Si la función con el nombre dado existe en el código, se ejecutará con los datos, si los hubiera, devueltos como un argumento a esa función.
JSONP es una forma de evitar la política del mismo origen del navegador. ¿Cómo? Me gusta esto:
El objetivo aquí es hacer una solicitud a otherdomain.com
y alert
al nombre en la respuesta. Normalmente haríamos una solicitud AJAX:
$.get(''otherdomain.com'', function (response) {
var name = response.name;
alert(name);
});
Sin embargo, dado que la solicitud va a un dominio diferente, no funcionará.
Podemos hacer la solicitud utilizando una etiqueta <script>
sin embargo. Tanto <script src="otherdomain.com"></script>
como $.get(''otherdomain.com'')
darán como resultado que se $.get(''otherdomain.com'')
la misma solicitud:
GET otherdomain.com
P: Pero si usamos la etiqueta <script>
, ¿cómo podríamos acceder a la respuesta? Necesitamos acceder a él si queremos alert
.
A: Uh, no podemos. Pero esto es lo que podríamos hacer: definir una función que use la respuesta y luego decirle al servidor que responda con JavaScript que llame a nuestra función con la respuesta como argumento.
P: ¿Pero qué pasa si el servidor no hace esto por nosotros y solo está dispuesto a devolvernos JSON?
A: Entonces no podremos usarlo. JSONP requiere que el servidor coopere.
P: Tener que usar una etiqueta <script>
es feo.
R: Las bibliotecas como jQuery lo hacen más agradable . Ex:
$.ajax({
url: "http://otherdomain.com",
jsonp: "callback",
dataType: "jsonp",
success: function( response ) {
console.log( response );
}
});
Funciona creando dinámicamente el elemento DOM de la etiqueta <script>
.
P: Las etiquetas <script>
solo realizan solicitudes GET. ¿Qué sucede si queremos realizar una solicitud POST?
A: Entonces JSONP no funcionará para nosotros.
P: Está bien, solo quiero hacer una solicitud GET. JSONP es increíble y voy a usarlo, ¡gracias!
A: En realidad, no es tan impresionante. Es realmente solo un hack. Y no es lo más seguro de usar. Ahora que CORS está disponible, debe usarlo siempre que sea posible.