M06UF4Pr2: JSONP: Receptes de cuina
RecipeXML i JSONP
Al començament de la UF, quan volíem accedir als fitxers XML que estan en un repositori comú i públic, vam tenir problemes degut a la política de domini únic. Ara que ja coneixem JSONP, estem en condicions de poder subsanar aquest problema.
Això és el que farem en aquesta pràctica.
La idea que s'ha comentat a classe és tenir un repositori amb tots els fitxers XML de receptes que han generat els alumnes. Aquest repositori és a:
En el servidor s'executa un script PHP que llegeix el fitxer xml. Per exemple:
- http://joanqc.no-ip.biz/iesbalmes/wec/receptes/read_xml_recipe.php?callback=foo&url=corn-chowder.xml
script read_xml_recipe.php:
<?php
//header('content-type: application/json; charset=utf-8');
header('content-type: text/plain; charset=utf-8'); //millor
header("access-control-allow-origin: *");
$url = $_GET['url'];
$xmlrecipe = file_get_contents('recipes22/'.$url);
echo $_GET['callback'] . '('.json_encode($xmlrecipe).')';
//echo $_GET['callback'] . '('.$xmlrecipe.')'; //així no!
?>
I des el domini local (localhost o qualsevol altre domini diferent de joanqc.no-ip.biz), podem accedir a aquests fitxers XML amb la tècnica JSONP, i parsejar-los.
script index_jsonp.html:
<html>
<head>
<meta http-equiv="content-type" content="text/html charset=utf-8" />
<title>Receptes AJAX</title>
<script>
function loadXMLDoc_jsonp(url)
{
tempscript = document.createElement("script");
tempscript.type = "text/javascript";
tempscript.id = "tempscript";
tempscript.src = "http://joanqc.no-ip.biz/iesbalmes/wec/receptes/read_xml_recipe.php?callback=JSONPHandler&url="+url;
document.body.appendChild(tempscript);
}
function JSONPHandler(data) {
//alert(data);
//document.getElementById("info").innerHTML = data;
txt="<h2>Ingredients</h2>";
txt = txt + "<ul>";
txt_ingredient = "";
txt_quantity = "";
txt_unit = "";
txt_fooditem = "";
//hem de parsejar el document XML que tenim a data
//http://www.w3schools.com/xml/xml_parser.asp
parser = new DOMParser();
xmlDoc = parser.parseFromString(data,"text/xml");
ingredients=xmlDoc.getElementsByTagName("ingredient");
for (i=0;i<ingredients.length;i++) {
//alert(ingredients[i].innerHTML);
for (k=0;k<ingredients[i].childNodes.length;k++) {
//alert(ingredients[i].childNodes[k].nodeName);
if (ingredients[i].childNodes[k].nodeName == "quantity") txt_quantity = ingredients[i].childNodes[k].childNodes[0].nodeValue;
if (ingredients[i].childNodes[k].nodeName == "unit") txt_unit = ingredients[i].childNodes[k].childNodes[0].nodeValue;
if (ingredients[i].childNodes[k].nodeName == "fooditem") txt_fooditem = ingredients[i].childNodes[k].childNodes[0].nodeValue;
}
txt_ingredient = "<li>" + txt_fooditem + " (" + txt_quantity + " " + txt_unit + ")</li>"
txt = txt + txt_ingredient;
}
txt = txt + "</ul>";
document.getElementById('info').innerHTML=txt;
}
</script>
</head>
<body>
<h1>Receptes (JSONP)</h1>
Les receptes estan en un repositori remot:
<ul><li><a href="http://joanqc.no-ip.biz/iesbalmes/wec/receptes/recipes/">http://joanqc.no-ip.biz/iesbalmes/wec/receptes/recipes/</a></li></ul>
<div id="formulari">
<form name="frm_receptes" id="formu" action="#">
<select name="recipes" onchange="loadXMLDoc_jsonp(this.value)">
<option value="">Escull una recepta</option>
<option value="corn-chowder.xml">corn chowder abs</option>
<option value="bean-and-ham.xml">Bean and Ham abs</option>
</select><br />
</form>
</div>
<div id="info">
</div>
</body>
</html>
creat per Joan Quintana Compte, febrer 2022