400 likes | 510 Vues
This guide explores the fundamentals of web services in HTML5, covering how to access and utilize them within web applications. It addresses key questions, such as how to discover and invoke web services, receive data, and update web pages dynamically. You'll learn about the technical specifications of web services, including URL location, data formats like XML and JSON, and the semantics of data. Additionally, the article highlights security issues related to same-origin policy and introduces JSONP as a potential workaround for cross-domain data requests.
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…