9.7. JSON Message![]() JSON, Marshal, Semantic, Serialize, YAML Figure 9-10. JSON Message![]() 9.7.1. Developer StoryDave is creating an Ajax calendar. The browser periodically polls for new appointments, which the server is sending as JSON messages. Since JSON messages are just JavaScript code for object creation, Devi's browser script needs only to run eval against each message in order to reconstruct the appointment. 9.7.2. ProblemHow can you transfer data between server and browser? 9.7.3. Forces
9.7.4. SolutionPass messages between server and browser in JavaScript Object Notation (JSON) format. JSON is a standard serialization format, created in 2002 as a cleaner and lighter alternative to XML. As with XML, the object can range in complexity from a simple string to a deep hierarchical structure. Also like XML, JSON is language-neutral, meaning that you could marshall a C++ object into JSON notation and unmarshall it to form an object in Perl. But in practice, JSON is particularly suited to browser-server communication because it's a format based on JavaScript. In fact, a JSON Message is JavaScript. This is a valid JSON Message: "Homer J." You can test browser-based JSON conversion on the Basic JSON Demo (http://ajaxify.com/run/json/). As you'll see there, the JSON Message "Homer J." maps to the JavaScript string, Homer J.. Here's a more complex example (as on the demo, reformatted): {"houseNumber":"742", "street":"Evergreen Terrace", "city":"Springfield", "postcode":"49007", "country":"USA", "comments": ["Deliveries accepted.","Familiar address, huh?",""] } As you can see, this JSON message is just a JavaScript object literal. You convert it like this: var name = eval("(" + nameJSON + ")"); Or like this (http://jibbering.com/2002/4/httprequest.html) if it takes your fancy: var name=new Function("return " + nameJSON)( ); Note that you don't even need a JSON library in the browser. The browser can pick up a JSON string using an XMLHttpRequest Call and simply run the standard eval function. However, there is actually a JavaScript JSON library (http://www.crockford.com/JSON/js.html), which adds two important capabilities: parse( ) for safer string-to-object conversion, and stringify( ) for object-to-string conversion. The former is an alternative to manual JavaScript evaluation, because evaling arbitrary messages puts your app at risk of running malicious JavaScript code. Thus, the string-to-object conversion should be executed if you don't trust the message. To parse a string, use the following codee: var name = JSON.parse(nameJSON); If you need to upload something to the server, you'll need to convert a JavaScript object to JSON with stringify( ). The Basic JSON Demo (http://ajaxlocal/run/json/) shows this conversion process too. The call looks like this: var nameJSON = JSON.stringify(name); So far, the examples have considered only JavaScript conversion. But JSON wouldn't be very useful if you could only convert to and from JavaScript objectsyou need to convert at the other end too, and your server side is probably not written in JavaScript. That's why there are JSON processors for many languages. Using these processors, you can easily share an object between JavaScript and your favorite server-side language. A remoting modification (http://ajaxify.com/run/json/remoting) of the Basic JSON Demo (http://ajaxify.com/run/json/) sends JSON to the server, using XMLHttpRequest Calls. There, it's converted to standard PHP objects using Michael Migurski's JSON-PHP library (http://mike.teczno.com/json.html). The library works similarly to JSON libraries for Java, .Net, and other languages. The following code converts JSON to a standard object: $json = new JSON( ); $newObject = $json->decode($jsonString); while the following code performs the reverse operation: $json = new JSON( ); $json = $json->encode($object); 9.7.5. Real-World ExamplesMany web sites use JSON as their data transfer format for shuttling data between browser and server. 9.7.5.1. KikoKiko (http://kiko.com) is an online calendar application with a slew of Ajax features (Figure 9-11). As you'd expect, the server holds a model of the calendar, and the browser keeps uploading changes using XMLHttpRequest Calls. JSON is the message format used for server responseseach response is a list of objects. Figure 9-11. Kiko![]() 9.7.5.2. Delicious JSON FeedDelicious (http://del.icio.us/doc/feeds/json/), a social bookmarking tool, provides a Web Service that exposes a user's recent bookmarks in the form of a JSON Message. For reasons discussed in On-Demand JavaScript (Chapter 6), this means a browser script can conveniently grab the data without the need for a Cross-Domain Proxy. 9.7.5.3. Route PlanningJim Ley's Route Planning application (http://jibbering.com/routeplanner/) shows you all the routes for a given airport (Figure 9-12), and, as his long-running XMLHttpRequest Tutorial (http://jibbering.com/2002/4/httprequest.html) explains, it uses JSON. For example, a JSON Message for the LAX airport is available at http://jibbering.com/routeplanner/route.1?LAX. What the browser receives from the following JSON Message is an XMLHttpRequest Call (... has been substituted for multiple data items): {from:'LAX',airports:[{id:"AMS",country:"NL",lat:"52.316666666667", lon:"4.7833333333333", tz:"Europe/Amsterdam",name:"Amsterdam",shortname:"Schiphol"},...,{id:"IAD", country:"US", lat:"38.95",lon:"-77.45",tz:"America/New_York",name:"Washington, DC", shortname:"Washington Dulles International"}],routes:[{carrier:"star",toAirport:"AMS", miles:5570},...,{carrier:"oneworld",toAirport:"DCA",miles:2304}]} Figure 9-12. Jibbering Route Planner![]() 9.7.5.4. Ajax.Net frameworkAjax.Net (http://ajax.schwarz-interactive.de/) is one of several Ajax Stub frameworks that uses JSON Messages to transfer data, which can easily be converted to and from native objects at either end. For more details, see "JSON Message" in the "Related Patterns" section of Ajax Stub. 9.7.6. Code Example: KikoKiko (http://kiko.com) responds to XMLHttpRequest Call with JSON Messages. When you log in, it downloads a list of appointments like this: [ {"title":"text","isevent":"bool", "picture":"text","starttime":"timestamp", "endtime": "timestamp","recurs":"int2", "recurend":"timestamp","insystem":"timestamp", "recurstart": "timestamp", "recurweek":"int2","description":"text","defaultfree":"bool","location": "text","apptid":"int8"},{"title":"Roundup meeting","isevent":"t","picture":"", "starttime": "2005-09-16 19:00:00","endtime":"2005-09-16 19:30:00","recurs":"1","recurend":"", "insystem": "2005-09-12 14:52:10.965713","recurstart":"2005-09-16 04:00:00","recurweek": "16","description":"Hopefully just a quick roundup","defaultfree":"f","location": "Cyberspace","apptid":"9222"}, {"title":"Go Home!","isevent":"t","picture": "","starttime":"2005-09-15 21:00:00","endtime":"2005-09-15 21:30:00","recurs": "0","recurend":"","insystem":"2005-09-12 15:00:33.659793","recurstart":"","recurweek": "","description":"","defaultfree":"f","location":"Office, Bar, Home","apptid":"9288"} ] Note that the message format here is a little unusual: everything is Strings, whereas JSON can store booleans and numbers directly. Consequently, the first element of the array includes some metadata to facilitate conversion, and the JavaScript includes a generic function to create native JavaScript objects from JSON messages like this. Kiko's browser script also includes some conversion to JSON, as shown below (though I was unable to exercise this code). Typically, requests in Kiko are made as POSTs with CGI-style parameters, and only the responses are JSON. var obj=json.stringify({'type':'newuser','email':email}) 9.7.7. Alternatives9.7.7.1. XML MessageJSON defines itself as a "fat-free alternative to XML." Before considering the differences between the formats, let's first look at what they have in common.
JSON Message has several advantages over XML Message (see earlier in this chapter):
XML Message (see earlier in this chapter) has several advantages over JSON Message:
9.7.8. Related Patterns9.7.8.1. Ajax StubBeing a portable object format, JSON is a useful way to facilitate calls from browser to server using an Ajax Stub (see earlier in this chapter) framework. 9.7.8.2. On-Demand JavaScriptSince a JSON Message is an ordinary JavaScript expression, it can be pulled in using On-Demand JavaScript. Data from external domains can be accessed this way, as explained in On-Demand JavaScript (Chapter 6). |