https://manuais.iessanclemente.net/index.php?title=Petici%C3%B3ns_AJAX_cross-domain_con_JSONP&feed=atom&action=historyPeticións AJAX cross-domain con JSONP - Historial de revisiones2024-03-29T14:28:47ZHistorial de revisiones de esta página en el wikiMediaWiki 1.36.2https://manuais.iessanclemente.net/index.php?title=Petici%C3%B3ns_AJAX_cross-domain_con_JSONP&diff=57896&oldid=prevVeiga: /* Programación no lado do servidor para responder a peticións JSONP */2016-01-20T18:18:15Z<p><span dir="auto"><span class="autocomment">Programación no lado do servidor para responder a peticións JSONP</span></span></p>
<p><b>Página nueva</b></p><div>= A problemática de seguridade coas peticións AJAX =<br />
<br />
Unha das limitacións das peticións AJAX é a de que non se poder facer peticións AJAX a dominios alleos ó dominio no que está aloxada a nosa aplicación, é o que se coñece como "Same-origin policy", para evitar que se carguen mediante JavaScript datos potencialmente inseguros por estar aloxados noutros servidores. É dicir que os datos que cargamos no noso propio dominio son considerados seguros, pero os que están noutros dominios de Internet non.<br />
<br />
Esta restricción pode evitarse si o dominio ó cal te conectas está configurado para aceptar conexións dende outros dominios. Isto consíguese activando a configuración "Cross-origin resource sharing" pero tamén pode solucionarse independentemente da configuración do servidor a través do uso de JSONP.<br />
<br />
== Aceptar por defecto peticións AJAX dende outros dominios en Apache (Autorización CORS) ==<br />
<br />
* Si queremos que o noso dominio acepte peticións AJAX dende outros dominios teremos que configurar o servidor web para responder a esas peticións:<br />
* Simplemente teremos que engadir a seguinte liña dentro de das seccións '''<Directory>, <Location>, <Files> ou <VirtualHost>''' que estarán no arquivo *.conf (httpd.conf ou apache.conf).<br />
<br />
* Outra opción tamén sería engadi-lo dentro dun arquivo '''.htaccess'''.<br />
<source lang="bash"><br />
Header set Access-Control-Allow-Origin "*"<br />
</source><br />
<br />
* Para asegurarnos que está correcto executaremos os seguintes comandos:<br />
<source lang="bash"><br />
# Activamos o módulo de cabeceiras en Apache (por defecto debería vir activado)<br />
a2enmod headers<br />
<br />
# Comprobamos o arquivo de configuración de Apache<br />
apachectl -t<br />
<br />
# Reiniciamos o servizo<br />
service apache2 restart<br />
<br />
</source><br />
<br />
= Cómo é JSONP =<br />
<br />
JSON e JSONP son basicamente o mesmo, un formato lixeiro para intercambiar datos con notación de obxecto de Javascript. A notación non cambia pero si cambia o "envoltorio". En JSONP en lugar de viaxar os datos a secas como en JSON, o que viaxa é unha función xeralmente chamada "'''callback'''". Esa función é como un JavaScript que engloba os datos que solicitamos. De ahí que o JSONP sexa coñecido como JSON con Padding.<br />
<br />
Exemplo de petición que devolve un JSONP:<br />
http://api.openbeerdatabase.com/v1/beers.json?callback=mifuncion&query=beer<br />
<br />
O que estamos recibindo é unha función como a seguinte:<br />
<source lang="javascript"><br />
mifuncion({ <br />
"page":1,<br />
"pages":1,<br />
"total":1,<br />
"beers":[ <br />
{ <br />
"id":87,<br />
"name":"Ginger Beer",<br />
"description":"A beer with authenticity and flavour, rich in ginger and citrus notes, spice with a malty sweetness.",<br />
"abv":2.5,<br />
"created_at":"2013-01-18T15:01:22Z",<br />
"updated_at":"2013-01-18T15:19:22Z",<br />
"brewery":{ <br />
"id":51,<br />
"name":"Adnams"<br />
}<br />
}<br />
]<br />
})<br />
</source><br />
<br />
<br />
= Por qué funciona o JSONP en diferentes dominios e non JSON =<br />
<br />
Para facer posible que JSONP funcione en situaciones cross-domain emprégase unha alternativa permitida á carga de scripts nunha páxina.<br />
Os navegadores sí que aceptan a carga de código JavaScript que se incorpore coa etiqueta <script> e o atributo SRC. É o método que empregamos para cargar por exemplo unha librería de jquery dende un CDN.<br />
<br />
<source lang="javascript"><br />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script><br />
</source><br />
<br />
Debido a que iso non provoca ningún problema de seguridade, JSONP aproveita ese formato para acceder dese modo ó recurso solicitado inxectando ese script na páxina e executando o código para extraer os datos.<br />
<br />
'''Atención: Si nos chegase un JSON normal non poderíamos executa-lo tal cual, xa que o JSON e un obxecto literal e non unha sentencia de Javascript que sexa capaz de executar o navegador, por iso non se podería meter entre as etiquetas SCRIPT da páxina.'''<br />
<br />
= Cómo se procesa un JSONP para extraer os datos =<br />
<br />
JQuery facilítanos esa tarefa. Simplemente teremos que indicarlle que o que estamos a recibir en un JSONP en lugar dun JSON.<br />
<br />
Se empregamos o método $.ajax teremos que indicarlle na variable de configuración '''dataType: "jsonp"''' en lugar de "json".<br />
<br />
Por exemplo empregando o método '''$.ajax()''' de jQuery:<br />
<br />
<source lang="javascript"><br />
<!doctype html><br />
<html lang="en"><br />
<head><br />
<meta charset="utf-8"><br />
<title>jQuery.getJSON demo JSONP</title><br />
<style><br />
img {<br />
height: 100px;<br />
float: left;<br />
}<br />
</style><br />
</head><br />
<body><br />
<div id="images"></div><br />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script><br />
<script> <br />
$.ajax({<br />
url: "http://api.openbeerdatabase.com/v1/beers.json",<br />
data: {<br />
query: "beer"<br />
},<br />
type: "GET",<br />
dataType: "jsonp",<br />
success: function(respuesta){<br />
console.log("Datos recibidos: ", respuesta);<br />
$("<pre>").text(JSON.stringify(respuesta)).appendTo("body");<br />
}<br />
});<br />
<br />
</script><br />
</body><br />
</html><br />
</source><br />
<br />
Na opción success a función que se executa contén un obxecto JavaScript nativo xa convertido para o seu uso inmediato.<br />
<br />
Podemos facer o mesmo exemplo anterior empregando o método '''$.getJSON()''' de jQuery moito máis sinxelo:<br />
<br />
'''Atención''': é necesario engadir un novo parámetro á URL. Ese novo parámetro é '''callback'''.<br />
Para facer iso pódese facer con '''?callback=?''' se é o único parámetro da URL ou ben '''&callback=?''' se é o último parámetro (xa temos máis na URL) que queremos engadir. '''É necesario engadi-lo para que xestione correctamente o JSONP'''.<br />
<br />
<source lang="javascript"><br />
<!doctype html><br />
<html lang="en"><br />
<head><br />
<meta charset="utf-8"><br />
<title>jQuery.getJSON JSONP</title><br />
<style><br />
img {<br />
height: 100px;<br />
float: left;<br />
}<br />
</style><br />
</head><br />
<body><br />
<div id="images"></div><br />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script><br />
<script> <br />
// Hay que engadir á URL o parámetro ?callback=? e jQuery encárgase do resto.<br />
$.getJSON("http://api.openbeerdatabase.com/v1/beers.json?callback=?",{query:"beer"},function(respuesta)<br />
{<br />
console.log("Recibes: ", respuesta);<br />
$("<pre>").text(JSON.stringify(respuesta)).appendTo("body");<br />
});<br />
</script><br />
</body><br />
</html><br />
</source><br />
<br />
= Programación no lado do servidor para responder a peticións JSONP = <br />
<br />
Os servidores tamén teñen que estar preparados para dar respostas a peticións de este tipo e para iso terán que facer algo como o seguinte exemplo en PHP que devolverá un JSONP cando se lle pasa como parámetro GET '''callback'''.<br />
<br />
O parámetro a pasar na petición dependerá do servidor ó que nos conectemos, pero si todos seguen o estandar deberían usar como parámetro GET '''callback''':<br />
<br />
<source lang="php"><br />
if (isset($_GET['callback']))<br />
echo $_GET['callback'] . '(' .json_encode($datos). ')';<br />
else<br />
echo json_encode($datos);<br />
</source><br />
<br />
--[[Usuario:Veiga|Veiga]] ([[Usuario discusión:Veiga|discusión]]) 19:18 20 ene 2016 (CET)</div>Veiga