Diferència entre revisions de la pàgina «M06UF4Pr2: JSONP: Receptes de cuina»
| Línia 1: | Línia 1: | ||
| − | + | __TOC__ | |
| + | =RecipeXML i JSONP (versió 1)= | ||
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. | 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. | ||
| Línia 29: | Línia 30: | ||
*http://localhost/M06/UF4/JSONP/index_jsonp.html | *http://localhost/M06/UF4/JSONP/index_jsonp.html | ||
| − | script '' | + | script '''recpetes_jsonp_v1.html''': |
<pre> | <pre> | ||
<html> | <html> | ||
<head> | <head> | ||
<meta http-equiv="content-type" content="text/html charset=utf-8" /> | <meta http-equiv="content-type" content="text/html charset=utf-8" /> | ||
| − | <title>Receptes AJAX</title> | + | <title>Receptes AJAX (JSONP)</title> |
<script> | <script> | ||
| + | |||
| + | let gloabal_url = ""; | ||
function loadXMLDoc_jsonp(url) | function loadXMLDoc_jsonp(url) | ||
{ | { | ||
| − | + | gloabal_url = 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) { | function JSONPHandler(data) { | ||
| − | // | + | //console.log(data); |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
//hem de parsejar el document XML que tenim a data | //hem de parsejar el document XML que tenim a data | ||
| Línia 61: | Línia 57: | ||
parser = new DOMParser(); | parser = new DOMParser(); | ||
xmlDoc = parser.parseFromString(data,"text/xml"); | xmlDoc = parser.parseFromString(data,"text/xml"); | ||
| − | |||
| − | + | let titol = (xmlDoc.getElementsByTagName("title")[0]) ? xmlDoc.getElementsByTagName("title")[0].firstChild.nodeValue : ""; | |
| − | + | let blurb = (xmlDoc.getElementsByTagName("blurb")[0]) ? xmlDoc.getElementsByTagName("blurb")[0].firstChild.nodeValue : ""; | |
| − | + | let genre = (xmlDoc.getElementsByTagName("genre")[0]) ? xmlDoc.getElementsByTagName("genre")[0].firstChild.nodeValue : ""; | |
| − | + | let author = (xmlDoc.getElementsByTagName("author")[0]) ? xmlDoc.getElementsByTagName("author")[0].firstChild.nodeValue : ""; | |
| − | + | let yield = (xmlDoc.getElementsByTagName("yield")[0]) ? xmlDoc.getElementsByTagName("yield")[0].firstChild.nodeValue : ""; | |
| − | + | let preptime = (xmlDoc.getElementsByTagName("preptime")[0]) ? xmlDoc.getElementsByTagName("preptime")[0].firstChild.nodeValue : ""; | |
| − | + | let preparation = (xmlDoc.getElementsByTagName("preparation")[0]) ? xmlDoc.getElementsByTagName("preparation")[0].firstChild.nodeValue.replace(/\\n/g,'<br />') : ""; | |
| + | let serving = (xmlDoc.getElementsByTagName("serving")[0]) ? xmlDoc.getElementsByTagName("serving")[0].firstChild.nodeValue : ""; | ||
| + | |||
| + | txt = `<h2>${titol}</h2>`; | ||
| + | |||
| + | txt += `<img src='recipes/img/${gloabal_url.replace('xml','png')}'/>`; | ||
| + | |||
| + | txt += `<h2>Capçalera</h2>`; | ||
| + | txt += `<ul>`; | ||
| + | txt += `<li>${blurb}</li>`; | ||
| + | txt += `<li>${genre}</li>`; | ||
| + | txt += `<li>${author}</li>`; | ||
| + | txt += `<li>${yield}</li>`; | ||
| + | txt += `<li>${preptime}</li>`; | ||
| + | txt += `</ul>`; | ||
| + | |||
| + | txt += `<h2>Ingredients</h2>`; | ||
| + | txt += `<ul>`; | ||
| + | x=xmlDoc.getElementsByTagName("ingredient"); | ||
| + | for (let i=0;i<x.length;i++) { | ||
| + | //=${b} | ||
| + | txt +=`<li>${x[i].firstChild.nodeValue}</li>`; | ||
} | } | ||
| − | + | txt += `</ul>`; | |
| − | + | ||
| − | + | txt += `<h2>Preparation</h2>`; | |
| − | + | txt += preparation; | |
| + | |||
| + | txt += `<h2>Serving</h2>`; | ||
| + | txt += serving; | ||
| − | + | document.getElementById('info').innerHTML=txt; | |
} | } | ||
| Línia 84: | Línia 103: | ||
<h1>Receptes (JSONP)</h1> | <h1>Receptes (JSONP)</h1> | ||
Les receptes estan en un repositori remot: | Les receptes estan en un repositori remot: | ||
| − | <ul><li><a href="http://joanqc.no-ip.biz/iesbalmes/wec/receptes/ | + | <ul><li><a href="http://joanqc.no-ip.biz/iesbalmes/wec/receptes/recipes22/">http://joanqc.no-ip.biz/iesbalmes/wec/receptes/recipes22/</a></li></ul> |
<div id="formulari"> | <div id="formulari"> | ||
<form name="frm_receptes" id="formu" action="#"> | <form name="frm_receptes" id="formu" action="#"> | ||
| − | + | <select name="recipes" onchange="loadXMLDoc_jsonp(this.value)"> | |
| − | + | <option value="bean-and-ham.xml">bean and ham</option> | |
| − | + | <option value="corn-chowder.xml">corn chowder</option> | |
| − | + | <option value="macarrons_de_la_parenta.xml">macarrons_de_la_parenta</option> | |
| − | + | <option value="conill_farcit_catalana.xml">conill_farcit_catalana</option> | |
| + | <option value="croquetes_levon_gukasyan.xml">croquetes_levon_gukasyan</option> | ||
| + | <option value="khash_levon_gukasyan.xml">khash_levon_gukasyan</option> | ||
| + | <option value="espaguetisBolonyesa.xml">espaguetisBolonyesa</option> | ||
| + | <option value="truitaPatates.xml">truitaPatates</option> | ||
| + | <option value="bolitas_rellenas_de_queso_Laura.xml">bolitas_rellenas_de_queso_Laura</option> | ||
| + | <option value="espaguetis_carbonara_Laura.xml">espaguetis_carbonara_Laura</option> | ||
| + | <option value="bunuelos.xml">bunuelos</option> | ||
| + | <option value="pollo.xml">pollo</option> | ||
| + | <option value="ous_de_guatlla_amb_bacon.xml">Ous de guatlla amb bacon</option> | ||
| + | <option value="carpaccio_de_peu_de_porc.xml">Carpaccio de peu de porc</option> | ||
| + | <option value="mandonguilles_de_sipia_i_marisc.xml">Mandonguilles de sípia i marisc</option> | ||
| + | <option value="pollastre_amb_salsifis.xml">Pollastre amb salsifís</option> | ||
| + | <option value="silpancho.xml">Silpancho</option> | ||
| + | <option value="charque.xml">Charque</option> | ||
| + | </select> | ||
</form> | </form> | ||
</div> | </div> | ||
| Línia 100: | Línia 134: | ||
</html> | </html> | ||
</pre> | </pre> | ||
| + | =RecipeXML i JSONP (versió 2)= | ||
| + | Què podem millorar de la versió 1? Si ens fixem, totes les receptes estan ''hardcoded'' dins de la select. Això vol dir que si pugem una nova recepta al servidor (via FTP, per ex), haurem d'actualitzar tota aquesta llista d'opcions. | ||
| + | L'objectiu de la versió 2 és que tinguem totes les opcions de les receptes generades de forma dinàmica. I això ho haurem de fer a l'inici de l'aplicació fent una consulta AJAX per saber què hi ha a dins de la carpeta de receptes. | ||
{{Autor}}, febrer 2022 | {{Autor}}, febrer 2022 | ||
Revisió del 10:36, 4 feb 2022
RecipeXML i JSONP (versió 1)
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 recpetes_jsonp_v1.html:
<html>
<head>
<meta http-equiv="content-type" content="text/html charset=utf-8" />
<title>Receptes AJAX (JSONP)</title>
<script>
let gloabal_url = "";
function loadXMLDoc_jsonp(url)
{
gloabal_url = 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) {
//console.log(data);
//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");
let titol = (xmlDoc.getElementsByTagName("title")[0]) ? xmlDoc.getElementsByTagName("title")[0].firstChild.nodeValue : "";
let blurb = (xmlDoc.getElementsByTagName("blurb")[0]) ? xmlDoc.getElementsByTagName("blurb")[0].firstChild.nodeValue : "";
let genre = (xmlDoc.getElementsByTagName("genre")[0]) ? xmlDoc.getElementsByTagName("genre")[0].firstChild.nodeValue : "";
let author = (xmlDoc.getElementsByTagName("author")[0]) ? xmlDoc.getElementsByTagName("author")[0].firstChild.nodeValue : "";
let yield = (xmlDoc.getElementsByTagName("yield")[0]) ? xmlDoc.getElementsByTagName("yield")[0].firstChild.nodeValue : "";
let preptime = (xmlDoc.getElementsByTagName("preptime")[0]) ? xmlDoc.getElementsByTagName("preptime")[0].firstChild.nodeValue : "";
let preparation = (xmlDoc.getElementsByTagName("preparation")[0]) ? xmlDoc.getElementsByTagName("preparation")[0].firstChild.nodeValue.replace(/\\n/g,'<br />') : "";
let serving = (xmlDoc.getElementsByTagName("serving")[0]) ? xmlDoc.getElementsByTagName("serving")[0].firstChild.nodeValue : "";
txt = `<h2>${titol}</h2>`;
txt += `<img src='recipes/img/${gloabal_url.replace('xml','png')}'/>`;
txt += `<h2>Capçalera</h2>`;
txt += `<ul>`;
txt += `<li>${blurb}</li>`;
txt += `<li>${genre}</li>`;
txt += `<li>${author}</li>`;
txt += `<li>${yield}</li>`;
txt += `<li>${preptime}</li>`;
txt += `</ul>`;
txt += `<h2>Ingredients</h2>`;
txt += `<ul>`;
x=xmlDoc.getElementsByTagName("ingredient");
for (let i=0;i<x.length;i++) {
//=${b}
txt +=`<li>${x[i].firstChild.nodeValue}</li>`;
}
txt += `</ul>`;
txt += `<h2>Preparation</h2>`;
txt += preparation;
txt += `<h2>Serving</h2>`;
txt += serving;
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/recipes22/">http://joanqc.no-ip.biz/iesbalmes/wec/receptes/recipes22/</a></li></ul>
<div id="formulari">
<form name="frm_receptes" id="formu" action="#">
<select name="recipes" onchange="loadXMLDoc_jsonp(this.value)">
<option value="bean-and-ham.xml">bean and ham</option>
<option value="corn-chowder.xml">corn chowder</option>
<option value="macarrons_de_la_parenta.xml">macarrons_de_la_parenta</option>
<option value="conill_farcit_catalana.xml">conill_farcit_catalana</option>
<option value="croquetes_levon_gukasyan.xml">croquetes_levon_gukasyan</option>
<option value="khash_levon_gukasyan.xml">khash_levon_gukasyan</option>
<option value="espaguetisBolonyesa.xml">espaguetisBolonyesa</option>
<option value="truitaPatates.xml">truitaPatates</option>
<option value="bolitas_rellenas_de_queso_Laura.xml">bolitas_rellenas_de_queso_Laura</option>
<option value="espaguetis_carbonara_Laura.xml">espaguetis_carbonara_Laura</option>
<option value="bunuelos.xml">bunuelos</option>
<option value="pollo.xml">pollo</option>
<option value="ous_de_guatlla_amb_bacon.xml">Ous de guatlla amb bacon</option>
<option value="carpaccio_de_peu_de_porc.xml">Carpaccio de peu de porc</option>
<option value="mandonguilles_de_sipia_i_marisc.xml">Mandonguilles de sípia i marisc</option>
<option value="pollastre_amb_salsifis.xml">Pollastre amb salsifís</option>
<option value="silpancho.xml">Silpancho</option>
<option value="charque.xml">Charque</option>
</select>
</form>
</div>
<div id="info">
</div>
</body>
</html>
RecipeXML i JSONP (versió 2)
Què podem millorar de la versió 1? Si ens fixem, totes les receptes estan hardcoded dins de la select. Això vol dir que si pugem una nova recepta al servidor (via FTP, per ex), haurem d'actualitzar tota aquesta llista d'opcions.
L'objectiu de la versió 2 és que tinguem totes les opcions de les receptes generades de forma dinàmica. I això ho haurem de fer a l'inici de l'aplicació fent una consulta AJAX per saber què hi ha a dins de la carpeta de receptes.
creat per Joan Quintana Compte, febrer 2022