Externe gegevens ophalen via JSONP
Last updated
Last updated
We hebben het al enkele malen aangehaald: het is perfect mogelijk een JSON-bestand van een ander domein in te lezen. De externe server moet deze cross-domain-data echter wel toestaan. U kan dus niet zomaar eender welk JSON-bestand vanaf een externe server inlezen.
Even zoeken op Google en u vindt voldoende JSONP aanbieders.
Om een JSONP request uit te voeren, hoeft u meestal aan het einde van de URL enkel de parameter callback=?
toe te voegen. Meer is het niet.
In deze voorbeelden gebruiken we enkel de methode $.getJSON()
, maar u kan perfect de methodes $.get()
, $.post()
of $.ajax()
gebruiken.
Voor deze oefeningen zijn we volledig afhankelijk van services van derden. Deze services kunnen in verloop van tijd wijzigen of zelfs helemaal verdwijnen. Het is dus best mogelijk dat tijdens het lezen van dit boek bepaalde oefeningen niet meer het gewenste resultaat opleveren.
De Internet Movie Database, of kortweg IMDB is een online databank met informatie over films, series en games. IMDB biedt voorlopig zelf nog geen eigen API aan, maar er zijn reeds verschillende externe hosts die voor u de gegevens in JSONP formaat kunnen aanleveren. Een van die hosts is http://www.omdbapi.com/.
Om seze service te kunnen gebruiken, moet u eerst een gratis apikey genereren!
De API is zeer eenvoudig. In onze toepassing verwerken we dadelijk drie parameters, namelijk t voor de titel, y voor het jaartal en plot. Al deze parameters zijn optioneel. Voor we de code bekijken kunnen we best eerst de structuur van de JSON response bestuderen.
★ Open ajaxLokaal/JSONP_imdb.html in een browser. ★ Open op deze pagina de voorbeeldlink Zoek Pulp Fiction.
Om de response zo klein mogelijk te houden, zijn alle overbodige spaties verwijderd. Dit maakt het ons wel extra moeilijk om de structuur te interpreteren. Gelukkig bestaat er een Chrome extensie JSON Formatter waarmee we JSON data kunnen herformatteren. (De link staat eveneens op de voorbeeldpagina.)
De structuur is nu makkelijk leesbaar. Een aantal van deze velden wordt in onze toepassing verwerkt. Let vooral op Poster. Dit veld bevat de URL naar de coverafbeelding.
★ Open ajaxLokaal/JSONP_imdb.html. ★ Vul in het hidden-field apikey uw eigen apikey in! ★ Bekijk de broncode en test het resultaat in een browser. ★ Zoek op pulp fiction.
Let in de code vooral op de structuur van het formulier!
Kies voor alle formuliervelden net dezelfde naam als de parameters in de API. Als we dadelijk het formulier verzenden, komen de juiste parameters automatisch correct in de URL terecht.
En nu het script. Omwille van de soms grote vertragingstijden, werken we bij het ophalen van externe gegevens best altijd met een preloader.
Zodra het formulier verzonden wordt (submit-event), gaan we met e.preventDefault()
voorkomen dat de pagina wordt omgeleid naar de URL op de form-tag (http://www.omdbapi.com/). Vervolgens wordt de preloader getoond.
De methode serialize()
leest alle formuliervelden uit, zet de naam + waardes om naar de juiste URL decoding en plaatst deze in een string.
Dit is tevens het correcte formaat waarin we de gegevens moeten doorsturen naar de API. Vervolgens maken we een JSONP request met als URL: http://www.omdbapi.com/?callback=?&t=pulp+fiction&y=&plot=short&apikey=xxxxxx
Let vooral op de extra parameter callback=?. Zonder deze parameter geen JSONP en dus geen resultaat!
De logica binnen de callback functie kennen we ondertussen. De gegevens worden uitgelezen en op de juiste plaats op de pagina getoond. Zodra alles verwerkt is, wordt de preloader verwijderd.
Nog een kleine opmerking over de afbeelding. Voor sommige films bestaat (nog) geen cover. Indien Poster de waarde N/A heeft, maken we #cover onzichtbaar.
GeoBytes geeft ons algemene informatie (coördinaten, land, munteenheid, ...) van steden over de ganse wereld.
★ Open ajaxLokaal/JSONP_stadsInfo.html. ★ Bekijk de broncode en test het resultaat in een browser.
In deze toepassing maken we gebruik van drie API's.
Links: GeoBytes API voor het tonen van de stadslijst.
Midden: GeoBytes API voor het tonen van de stadsinfo.
Rechts: Yandex Maps API voor het stadsplan.
Meer info over de gebruikte API's vindt u hier:
Als voorbeeld gaan we zoeken naar alle steden die de tekenreeks antw bevatten.
★ Open http://gd.geobytes.com/AutoCompleteCity?q=antw in een browser. ★ Herformatteer het resultaat met JSONlint.
De details kunnen we opvragen via een tweede URL op GeoBytes.
★ Open http://gd.geobytes.com/GetCityDetails?fqcn=Antwerp,+AN,+Belgium in een browser. ★ Herformatteer het resultaat met JSONlint:
(De waarde voor de parameter fqcn kan u eventueel kopiëren uit voorgaande array.)
De coördinaten geobyteslatitude en geobyteslongitude uit dit bestand gebruiken we om een statische afbeelding op Yandex te berekenen.
★ Open de afbeelding in een browser: ★ https://static-maps.yandex.ru/1.x/?lang=en-US&z=12&l=map&size=400,400&ll=4.417000,51.216999&pt=4.417000,51.216999,pm2rdl1
Als we dit nu allemaal combineren, krijgen we volgende code:
Het keyup-event wordt getriggerd vanuit het zoekveld q. Indien dit veld meer dan twee karakters bevat, komt de eerste JSON request in actie. De gegevens die we als een array ontvangen, worden in een ul-lijst verwerkt. Eerst worden de oude items uit de lijst gewist en daarna wordt de lijst opnieuw opgebouwd.
Telkens we de muis op één van de steden plaatsen (mouseenter) worden de stadsdetails opgevraagd en wordt het middenstuk geüpdatet. Met de coördinaten kunnen we via de Yandex API een nieuwe afbeelding ophalen.
Merk op dat de stadslijst volledig dynamisch wordt opgebouwd. Op een dynamisch gegenereerde lijst kunnen we enkel het on-event gebruiken.
Goed: $('#stadslijst ul').on('mouseenter', 'li', function(){...})
.
Fout: $('#stadslijst ul li').mouseenter(function(){...})
.
Werkt u liever met deze methodes, vergeet dan niet het juiste formaat te vermelden.
De URL-parameter callback=?
komt dan te vervallen.
$.get('url', function(data) {...},
'jsonp'
);
$.post('url', function(data) {...},
'jsonp'
);
$.ajax({..., dataType:
'jsonp'
, ...});