400 likes | 508 Views
HTML5 Communication. The Setup. Somewhere on the web, a server makes a ”service” available, that we wish to use in a web application The service may offer certain data or a certain functionality. Server. Service. Web App. The Setup. Main questions to answer:
E N D
The Setup • Somewhere on the web, a server makes a ”service” available, that we wish to use in a web application • The service may offer certain data or a certain functionality Server Service Web App
The Setup • Main questions to answer: • How do we get to know a web service? • How do we invoke a web service? • How does data come back? • Once we have received data, how do we update our page? • What can go wrong?
What is a Web Service? • Essentially a specification of location, format and semantics • Location: the URL • Format: Which standard does the data exchange follow (XML, JSON,…) • Semantics: What does the returned data mean • Some public web services can be found at http://www.service-repository.com/
What is a Web Service? • Of course, the web service might we developed by ourselves… • In any case, we can get in contact with a web service using an HTTP Request message • More specifically, we use the class XMLHTTPRequest
HTTP Request in JavaScript // Location of the web service var url = ”http://someserver.com/data.json” // Setting up the request var request = new XMLHttpRequest(); request.open(”GET”, url);
HTTP Request in JavaScript // Call this when data comes back request.onload = function() { if (request.status == 200) { var data = request.responseText; // Process data } }; // Now actually send the request request.send(null); // No data sent along
HTTP Request in JavaScript • The returned data is stored in the responseText property • Data is in text format, but could be • XML • JSON • … • Up to the processing code to ”make sense” of the returned (text) data
HTTP Request in JavaScript • Things to notice about XMLHTTPRequest • Does not work with local files! Due to security issues… Works with local web server • The request.onload property is part of XMLHTTPRequest level 2. Only supported by newer browsers (most noteworthy IE9+). Level 1 implementation is not much harder, though…
The JSON data format • The trend in web data exchange format is going towards JSON (and away from XML) • JSON – JavaScript Object Notation • Why…? • Simpler specification…? • More light-weight than XML…? • The latest fashion…?
The JSON data format • What can JSON do for us? • Turn a JavaScript object into a string • Turn a string into a JavaScript object (if possible) • Another variant of the serialize/deserialize concept
The JSON data format • Two central JSON methods: • stringify: turn an object into a string • parse: turn a string into an object str = JSON.stringify(obj) Object obj String str obj = JSON.parse(str)
The JSON data format • So, we get a string back from the request… • …and we can convert it to a JavaScript object • Obviously, we need some details about the object in order to properly process it • The publisher of the web service must provide such details…
The JSON data format • Once we have converted the data to a true object, we would typically • Process the object, extracting relevant data • Use the data to update the web page, by altering the DOM through JavaScript
A security issue… • The mechanics for retrieving data across the web are fairly straightforward • However, security can get in the way… • All browsers enforce the same-origin policy
A security issue… • You can do this… GET www.1.com/showdata.html Client www.1.com (page comes back) Page makes XMLHTTPRequest to www.1.com/getdata (data comes back)
A security issue… • You can not do this… GET www.1.com/showdata.html Client www.1.com (page comes back) Page makes XMLHTTPRequest to www.2.com/getdata www.2.com (data does not comes back)
A security issue… • Or in plain English: • Browsers prevent you from making XMLHTTPRequests to domains other than the original domain the page was served from
A security issue… • This is rather severe – we will often like to get data from e.g. a third-party source • Easy solution – just copy pages to data source, and let that server serve the page itself • Often we do not have that privilege… • Enter JSONP!
JSONP • JSONP – JSON with Padding • Not a very good name… • General idea: Get back a piece of (JSON) data by ”disguising” it as a bit of JavaScript
JSONP • Observations: • You can not make an XMLHTTPRequest to an arbitrary domain (same origin policy) • You can link to JavaScript code from any source on the Web
JSONP • Further observations • A piece of linked-to JavaScript can (obviously) execute in your browser • A piece of linked-to JavaScript can (obviously) call its own methods in your browser • A piece of linked-to Java can (maybe not so obviously) call a method that you have defined in your own JavaScript code
JSONP • First attempt: Just include a <script> tag on your page, and link to a source that returns ”raw” JSON data <script src=”http://www.1.com/rawJSON”> </script>
JSONP • First attempt will not work, because the browser will interpret the returned data as JavaScript…and fail • JSON data is not JavaScript…
JSONP • Second attempt: Instead of returning raw JSON data, now ”wrap” that data in something that looks like a JavaScript method call: • Replace: rawJSONdata • with: someMethod(rawJSONdata)
JSONP • Second attempt could work; the returned data is valid JavaScript, and can be executed if we have defined the method someMethod in our own JavaScript code • The browser parses and interprets the return-ed code, so when it reaches our method, the JSON data is now an actual object!
JSONP • Problem with second attempt: User must know what method name the returned code will use • Third attempt: Let the user specify the name of the method to call (i.e. a callback method) <script src=”http://www.1.com/service? callback=myOwnCallback”> </script>
JSONP • Now the server will return the requested data wrapped inside a call to the callback method we have specified: • Replace: someMethod(rawJSONdata) • with: myOwnCallback(rawJSONdata)
JSONP • Remember, all of this only server one purpose: Retrieving data from an arbitrary domain • Isn’t it a big, dangerous hack…? • A hack: Well, maybe using the script tag for something it was not intended for… • Dangerous: Not more – or less – dangerous than linking to external JavaScript in general
JSONP • JSONP works, but is still somewhat controver-sial – the server could return any JavaScript code it chooses • Work in progress concerning safer alternatives and/or more restrictive JSONP versions • See e.g. www.json-p.org
Repetitive data retrieval • Now we can retrieve data from ”everywhere” (that supports JSONP) on the Web • Still a ”one-off” deal – once we have data, how can we get in again? • Might be relevant to refresh data regularly • Traffic conditions, tweets, stock quotes, etc.
Repetitive data retrieval • We wish to make the page refresh itself (without user interaction) • A page refreshes ifself when a new piece of JavaScript is added to it (thus executing the newly added JavaScript) • So, could we periodically add a new piece of JavaScript to a page…?
Repetitive data retrieval • We can use two tools: • We can attach a timer to a page, using the setInterval method • We can insert any element we wish into the DOM using JavaScript, even a <script> element
Repetitive data retrieval • Using a timer: setInterval(timerCallback, 1000); • This means: every 1000 milliseconds, call the method timerCallback
Repetitive data retrieval • What should we do in the callback method? • Insert a new <script> element on the page • If a <script> element is already there, remove it, and insert a new <script> element • Else just insert the new <script> element
Repetitive data retrieval // Called whenever timer expires function timerCallback() { var url = ”…”; // The JSONP-based web service var newSE = document.createElement(”script”); newSE.setAttribute(”src”, url); newSE.setAttribute(”id”, ”jsonp”); var oldSE = document.getElementById(”jsonp”); var head = document.getElementByTagName(”head”)[0]; if (oldSe == null) { // This will happen the first time head.appendChild(newSE); } else { head.replaceChild(newSE, oldSE); } }
Avoid being cached… • If the URL in the <script> tag is always the same, the browser might cache the retrieved data – we don’t want that! • Solution: Make each URL unique by appending a ”random” value to it…
Avoid being cached… • Replace var url = ”…”; • With e.g. var url = ”…” + (new Date()).getTime();
JSONP vs. XMLHTTPRequest • Page and data have same origin • Do what you prefer (and what is supported) • Page and data have different origin • Only option is JSONP • Only link to trusted locations
We are done, but… • Remember, all of this only helps you retrieve data from an external source • The processing of data (getting rid of duplicates, handling meaningless data, etc.) is still entirely up to you…