When you’re working with JSON, performance and security are often opposing, yet equally important concerns. One of these areas of contention is handling the JSON strings returned by a server. Most JavaScript libraries do a great job of abstracting away the details, but the underlying process has long been a frustrating exercise in compromise.

On one hand, eval() is the fastest widely available method, but it is not safe.

On the other hand, textual JSON parsers written in JavaScript may be much safer, but are dramatically slower. In client-side situations, where milliseconds count, such a large performance overhead is typically too prohibitive to accept.

Recently, an exciting new alternative has emerged: browser-native JSON parsing. Integrating JSON parsing as part of the browser’s implementation of JavaScript allows for using the more secure parsing method, and even provides performance faster than eval() offers.

To take advantage of that, this post will show you how to detect whether or not a browser supports native JSON parsing, and how to force jQuery to use browser-native parsing in its $.ajax calls when it is available.


Native JSON parsing in the browser

Previously known as ECMAScript 3.1, ECMAScript “Fifth Edition” (the specification that JavaScript implements) formally codifies a native JSON parsing feature. The spec’s API exactly mirrors that of Crockford’s implementations of JSON.parse and JSON.stringify in json2.js, easing the transition to browser-native functionality.

This native JSON parsing brings marked improvements in terms of both security and performance. Not only does the native routine use textual parsing to avoid the risk of executing malicious code embedded within JSON, but it is also fast.

At the time of this writing, three major browsers already include support for native JSON parsing: IE8, Firefox 3.5, and Chrome 3.

Safari 4 does not currently support the standard, but its underlying engine (WebKit) has recently implemented it. Hopefully the feature will make its way to Safari soon.

Detecting native JSON support

Determining whether or not native JSON parsing is available within a given browser is the first problem we need to solve. To do this, we ultimately need to know if the JSON.parse function is defined.

We can’t test for JSON.parse directly because attempting to reference it will throw a JavaScript error if the underlying JSON object doesn’t exist. So, first we need to inspect the type of that underlying object itself:

If we find that the JSON object does exist, it’s likely that native JSON parsing is available. However, it’s a best to double check the JSON.parse function as well:

Because JavaScript performs short-circuit evaluation, it’s safe to clean this up by combining both tests in a single conditional, as long as they’re in this order:

Curious whether your browser supports native JSON parsing? Using the JavaScript above, I have determined that:

Extending jQuery to use native JSON parsing

In my previous post, I demonstrated how to use jQuery’s dataFilter to transform a JSON response before it is returned to the $.ajax() success handler. In the process, we also preempted jQuery’s default method for deserializing JSON data.

The focus at that time was implementing the same method for JSON parsing that jQuery uses by default, so eval() was still used. However, we can also use the same dataFilter mechanism to force browser-native JSON parsing instead.

Using our JSON parsing detection code and a dataFilter callback, upgrading jQuery to use browser-native parsing is simple:

Because jQuery only attempts to deserialize JSON responses if their type is string, and because the dataFilter callback executes before jQuery would normally perform that deserialization, this technique preempts jQuery’s JSON evaluation completely. In the worst case, it will simply revert back to the same eval() method that jQuery internally uses by default anyway.

Note: It’s important to keep in mind that the dataFilter will run regardless of what type is actually returned from the server. You should only use this when you’re sure that you’re receiving a JSON string.

Conclusion

If you’ve been paying close attention to jQuery’s ongoing development, you may already know that jQuery 1.3.3 will provide functionality very similar to what I’ve shown you. I decided to go ahead and write this post anyway for a few reasons:

  • You can use this today, without waiting for jQuery 1.3.3.
  • You can use this in previous versions of jQuery, if upgrading isn’t feasible for you (as is often the case with plugins dependent on older versions).
  • If you use my technique for isolating your code from ASP.NET AJAX’s “.d”, you will still need a method for deserializing JSON in the dataFilter.

Speaking of that last point, if you’re using jQuery with ASP.NET AJAX services, be sure to watch out for the next post in this (accidental) series. There is at least one more productive step left in improving this workflow that I have been using in my projects and want to share with you soon.