Introduction

Thanks to the increasing use and education of efficient JavaScript techniques in today’s web applications, JSON has become the data format de jour of the enterprising young web developer. JSON is particularly useful at loading state—passing and loading data that is unique to a particular client. The question we’ve run into around here, is what is the best way to get data off of our server and into a JSON object so it can be processed by the browser? Turns out, there’s a few ways to handle it and they each come with a few caveats. Today we’re going to examine four different approaches to creating a JSON object on page load (Ajax, innerHTML, Embedded Script Tags and Server Processed JavaScript) and discuss the pros and cons of each method.

Note: Some of the example code presented below uses the JSON Parser and Prototype Framework. You may need to grab yourself a copy of each if you want to follow along.

HTML Form Builder

The Concept

Just to make sure we’re all on the same page, let’s do a quick rundown of why it’s important to figure out how to load a JSON object on page load. A typical web page may pull data from the server, and arrange all the data in proper XHTML markup form with only server side processing (like PHP). But on JavaScript intensive web sites (like most web applications), JavaScript may be needed or involved in the initial page load before everything is ready to play and interact with. In these cases, the data is pulled from the server, sent to JavaScript (via a JSON friendly format) where the script then places the data into the markup accordingly. Imagine the data was static, the JavaScript may look similar to this:

user = {"first":"Ryan", "last":"Campbell"}
drawName(user);function drawName(user) {
    // modify the DOM with the information
}

An object is created, and the data from that object is placed into the DOM. Unfortunately, most sites have data coming from a database and aren’t static. So how is that a user object is created? That’s what we’ll look at with the following four approaches. For each approach, we will take a look at the code required to populate the user object with the necessary data.

Ajax

Everyone’s favorite new candy. What better way to load data than with the ever popular Ajax? Well, it isn’t exactly the best approach performance-wise in my opinion, but it does have its uses depending on your development preferences. Here’s how it usually works: onload a script executes an Ajax request that queries the server for a JSON string. The server sends back the string, and the string is then converted into an object.

var myAjax = new Ajax.Request(
    'url-to-server',
    {method: 'post', parameters: 'action=lookupUser&id=23, onComplete: function(r) {
            user = JSON.parse(r.responseText);
        }
    }
);

Once the server sends back the response, JSON.parse() then converts our string into the actual JavaScript object. From there, we can then have JavaScript modify the DOM with the data.

While I haven’t seen this method used much in my experience, there are two definite benefits: it provides consistency and you don’t have to depend on a global variable. For an example of consistency, we can look at something like paging. When the user clicks on a “Next” link to receive something like the next 20 results from a search, the Ajax request that fires onclick is exactly the same every single time. With the Ajax method, we can also use the very same request to run onload, so that you can isolate where your data is coming from ahead of time. The important thing is to analyze the usage of common objects on the server. Also, it’s nice to know exactly where your user object is being created. As we’ll see in some of the other approaches, the user object must be initialized in a global variable.

What’s wrong with this method? Well, usually when a page loads up, the server establishes a database connection and initializes common objects. That means calling a simple function, such as lookupUser(23), takes very little additional resources since only one extra query is being made. To call this same function through an Ajax request requires us to create a new HTTP request, a new database connection, and the re-initialization of common objects. The performance hit to me just isn’t worth it if the other methods are available.

innerHTML

The innerHTML approach relies on populating HTML elements (like a hidden div) with data from the server and them having JavaScript fetch the innerHTML of those elements onload via the very quick document.getElementById or popular $() function.

// The HTML
<div id="jUser" class="hide">{"first":"Ryan", "last":"Campbell"}</div>// The JavaScript
user = JSON.parse($('jUser').innerHTML);

Using innerHTML to send JSON to the client has promise, but the practical usage is limited because of it’s strike against the separation of layers. In our ideal programming environment, CSS, HTML and JavaScript are individual layers. This works out nice so that designers can make changes without having to look at code, and developers can make changes without considering CSS. While you could think of JSON as just content and therefore justify to yourself that it does have its place in the markup, it’s a bit of a stretch.

Let’s examine if the JSON object is describing the appearance or layout of the page. The following code tells the JavaScript what type of user is being loaded. After the JSON is read by the JavaScript, the JavaScript could then add/remove markup accordingly.

{"first":"Ryan",
 "last":"Campbell",
 "rank":"Admin",
 "country":"United States",
 "template":"header"}

Given the JSON, the JavaScript could display a different, customized header for each type of user. Also, the designer can go in and change the fairly human readable string without having to open a JavaScript file, which will then change the appearance of the page. Another benefit of this method is, like the Ajax approach, it removes dependencies on global variables. They share the same weakness as well in the fact that a JSON parser is needed to read the string.

One major hassle with the innerHTML approach is escaping in JSON strings. Escaping an actual JSON object in JavaScript is weird enough, but then trying to escape an HTML string that will be parsed into JSON seems to multiply the confusion. Here is an example of escaping a link in JavaScript:

obj = {"item":"<a href=\"particletree.com\">link</a>"};

If we were to place that same code into the HTML, the parser would break. If the tags are replaced with &lt; and &gt; it will work, but they would have to be converted back to tags on the JavaScript side. Overall, it leads to some serious code ugliness.

Embedded Script Tags

Instead of putting a JSON formatted string into the markup, we can instead place an actual JSON object with an embedded script tag. Similar to the innerHTML approach, the server will load up the content in the flow of the markup. This time, though, it will print out script tags containing the information instead of placing it inside of an element.

<script type="text/javascript">
    <!--
    user = {"first":"Ryan", "last":"Campbell"}
    -->
</script>

With this, any other JavaScript file can reference our global user object. Other than the reliance on a global variable, this method is fairly rock solid. Since JSON is native to JavaScript, no outside library or parser is needed. While the speed increases are actually minimal, it is still pretty good practice to trim down code when possible. It also creates a healthy dose of separation. Even though the JSON is still in the HTML file, it is in a separate script section and can still be easily configured. Finally, all character escaping is based off of JavaScript rules rather than a quirky combination of HTML and JavaScript.

Server Processed JavaScript

This approach is identical in concept to embedded script tags, but it takes things a step further. By setting up the server to process JavaScript as PHP (or any desired server language), we can include PHP processed strings right in the JavaScript. If we process js files as PHP (with a little htaccess tweaking), the following code would still produce valid JavaScript:

user = <?php lookupUser(23); ?>;

The code above will execute with the rest of the server code, and will ultimately output:

user = {"first":"Ryan", "last":"Campbell"}

Like embedded script tags, a global user object is created, but this time, the object is actually created in the JavaScript file, and not on the HTML page. This allows for complete separation. By including the JavaScript file in the HTML page, everything just works regardless of what is on the HTML page. It’s also nice to know that all resources needed by the JavaScript file are located within the JavaScript file. This makes everything easier to track, and reduces confusion when you’re trying debug.

As always, nothing is perfect. While this method is great in plug and play reusability, it makes caching the JavaScript file an impossibility and turns out to be limited in catch all circumstances. For example, we have a global JavaScript file on every page using this technique. However, we don’t want the JavaScript to execute on every page. For the three other methods, we can just place code to catch it:

if(user) doSomething();

By excluding the JSON, you prevent something from happening. In this case, the user object will always be created. Now, on the PHP level a check could be made to make the user object null in certain circumstances, but that leads to inevitable complications. It is much easier to just not include something in the innerHTML div or between our embedded script tags.

Which to Choose

I have used all four of these methods in projects, and they all get the job done. For most smaller scale operations, any of these will work and you won’t have to think twice about it. Personally, I find embedded script tags to be superior because they allow for flexibility, don’t require custom server configurations, and are native to JavaScript. And I try to stay away from the Ajax version the most mainly because the hits to the server really aren’t worth it when there are satisfactory alternatives available. The key is to pick one method and stick with it as often as possible for the sake of consistency.

HTML Form Builder
Ryan Campbell

Loading Content with JSON by Ryan Campbell

This entry was posted 4 years ago and was filed under Features.
Comments are currently closed.

· 21 Comments! ·

  1. Aditya Mukherjee · 4 years ago

    You missed out the ever famous dynamic script tag method, where you can append a new [style src=’path-to-json’ type=’text/javascript’], with a specified callback. I think that’s the easiest method to work with JSON, although it does remove the option of passing more than one argument to your function (unless you control your JSON to output the function accordingly)

  2. Aditya Mukherjee · 4 years ago

    I meant [script] in the previous comment! :P Sorry!

  3. Ryan Campbell · 4 years ago

    Yeah, that’s true. Dynamic script tags could have gotten their own category. For the most part, they have all of the same negatives as Ajax. I’m not a fan of them myself, but they are a viable option.

  4. brett · 4 years ago

    The JSON library at the url above does not appear to have a JSON.parse method. It looks like the method has been moved to the String object: string.parseJSON(). Either way you could just use javascript’s built in eval() method to parse a JSON string, which is exactly what string.parseJSON does.

  5. Nephilim · 4 years ago

    Not to be all AJAX-fanboy-ish, but I think you’re selling the advantages of AJAX a bit short here. It’s true that AJAX is not appropriate for the cited example, but AJAX shines when (a) you don’t know ahead of time what data you want to put on the page, or (b) you want to be able to replace data on the page with new, updated information, or (c) you want to display a dynamic subset view of a very large data set.

    For example, if you were having to browse through a directory of thousands of users, embedding the information statically in the HTML becomes far less practical, because not only are you having to send all the information to be browsed, but the database connection must provide all possible data to be viewed. There’s a break point where the extra initial database connection with AJAX pays dividends in bandwidth and convenience for the end user, I think.

    Still, for most of us, we more often encounter cases like the one in your article than ones which are more suited to AJAX. Often, AJAX is a hammer looking for a nail. So it’s good to see some frank analysis on the differences between embedded approaches like this. Thanks for the interesting read!

  6. Frank · 4 years ago

    Thanks for that interesting article. You’re pointing out what I discover on several web pages: Many of them use the onLoad event and trigger an (unneeded) Ajax request (using fancy status bars) only to show they’re part of the whole web 2.0 community. I’d rather save some bandwidth, keep the server’s workload as low as possible and actually have the server respond quickly when it’s really making sense.

  7. Nathan Smith · 4 years ago

    Nice article. I like that you presented all of the common options, and balanced them with pros and cons. I just wanted to point out that according to Douglas Crawford, HTML comments within script tags are no longer necessary, a relic of days gone by in which the script tag may not have been recognized.

  8. Ryan Campbell · 4 years ago

    Thanks Nathan, good to know.

    Nephilim, I am far from anti Ajax. I use it all over the place. I was strictly trying to keep this article on practices to use during page load. I did mention paging as one example Ajax is good for. Also, which you touched on, is when there is a ton of content. It would not be efficient to write an extremely large JSON string to the page. It would be much easier to write one in chunks, or fetch the data with Ajax.

  9. Mr. Nice · 4 years ago

    Wow… terrific…

  10. Joshua Curtiss · 4 years ago

    Whereas your article was a fun read, I feel like I’m missing something. In conjunction with Nephilim’s comments, the point of AJAX is for all the functionality you get AFTER your initial page load. Isn’t all of this overkill if you just want some static data on the initial load? Haven’t we been doing that with server-side code that writes the content directly into the HTML for years?

    The server processed external JavaScript file is a fascinating idea, and you could even put URL parameters right in the script tag’s href to specify the data you want, but even then this feels like overkill if you’re just looking for injecting initial data at page load.

    I’m sorry, I’m sure I’m just missing something here, and gladly welcome the clarification.

  11. Dave Kees · 4 years ago

    If you’re going to use the Prototype Framework, don’t forget that you don’t need to parse or evaluate JSON objects on the client-side. You can create them on the server-side and put them in a x-json header for your response. The Prototype Framework will automatically try to take information in a x-json header and make it a JSON object. Read more here: http://prototypejs.org/api/ajax/request. Just scroll to the bottom and look for the header “Evaluating JSON headers” in the prototype docs.

  12. Frederic Torres · 4 years ago

    On a different note I like to use JSON for test data driven rather than CSV or XML. I wrote a post about it. http://blog.incisif.net/2006/12/19/csv-xml-or-json-for-data-driven-testing.aspx

    http://www.InCisif.net Web Testing with C# or VB.NET

  13. Tobie Langel · 4 years ago

    Hi Ryan,

    I suggest you have a look at Prototype’s first release candidate for version 1.5.1 which comes with full JSON support.

    Great article - as usual!

  14. Ryan Campbell · 4 years ago

    Joshua, I have found that as I write more complex JavaScript, the redundancy of writing something on the server and then modifying it with the JavaScript at a later point is too much. So, if I have a few routines with complicated logic that control the display on the page, it is easier for me to keep all of the logic in one place than it is to break it up. This article is for those cases when the display logic is easier kept in the JavaScript, but you still need a way to pass the data to the display logic.

  15. Jason · 4 years ago

    You should go back to some of your old entries (such as “replacing trackback with blog search”) and remove all the spam comments… it’s kind of embarrassing!

  16. Josh Fraser · 4 years ago

    Ryan, thanks for a great read. I whole-heartedly agree with everything you said. AJAX has all the hype, but I’m not convinced it is always the best implementation. I agree that server processed JavaScript is a good way to keep everything all in one place, keep your code a little shorter, and make thing easier to debug.

  17. Adhatoda · 4 years ago

    @ Ryan “This article is for those cases when the display logic is easier kept in the JavaScript, but you still need a way to pass the data to the display logic.” Yepp, absolutly!

  18. Murtaza · 3 years ago

    Hey Ryan any chances we might see an article on the wufoo’s searching on data entering page - the page where its written “Display entries that meet any/all of the following conditions” I really need to do similar thing in one of my project, now not sure how to do advance searching I mean how do I construct php query from an html form submitted by user, there many ways, not sure which one suits best :(

  19. hh · 3 years ago

    Everyone needs a hug.

  20. Oren · 3 years ago

    Liked your article and… you should always remmember the Security Breach using JSON with your API inputs, because it can includes user malicious functions.

  21. Martin parry · 3 years ago

    I’m using Ajax on my sites - This has been a great read thanks.