Native JSON in IE8
As you may have guessed from the title of this post, Internet Explorer 8, as of Beta 2, offers native JSON parsing and serialization. This new native JSON functionality enables Internet Explorer 8 aware AJAX applications to run both faster and safer!
What’s JSON?
For those of you that are not die hard AJAX developers, allow me to provide a bit of background. JSON is a simple human readable data interchange format often used by AJAX applications when transmitting data between the server and the web application.
For example, imagine that you select a contact name from your favorite web mail client so that you can see the contact information. The server might send down a stream of data to the web application (which is running in the browser) that looks like this:
{
"firstName": "cyra",
"lastName": "richardson",
"address": {
"streetAddress": "1 Microsoft way",
"city": "Redmond",
"state": "WA",
"postalCode": 98052
},
"phoneNumbers": [
"425-777-7777",
"206-777-7777"
]
}
Fortunately, this format is syntactically compatible with Javascript. Many applications today will use the Javascript eval() function to convert the data payload into a Javascript object. Using eval() is a dangerous and expensive approach. eval() parses the string as a general Jscript expression and executes it. If the string being passed to eval() has been tampered with, it could contain unexpected data or even someone else’s code – which is now injected into your web application.
There are libraries, written in Javascript, that are designed to more safely parse untrusted JSON payloads. Some libraries do a strict verification of the data payload using a parser written in Jscript (https://www.json.org/json_parser.js). Some libraries, like json2.js, do a sanity check on the input string using a regular expression then use the faster eval() for parsing . The ideal solution is a native implementation that protects the application from code injection, is fast and available everywhere.
Native JSON in IE8 Jscript
The Jscript engine for IE8 now has a full native implementation of JSON that significantly improves the speed of serialization, deserialization and improves the overall safety of parsing untrusted payloads while maintaining compliance with JSON support as described in ES3.1 Proposal Working Draft
APIs
We defined a new built-in object ‘JSON’. The object can be modified or overridden. It looks like math or any other intrinsic global object. In addition to the JSON object, special functions, toJSON() , are added to the prototypes of Date, Number, String, boolean objects. The JSON object has two functions: parse() and stringify() .
Example:
var jsObjString = "{\"memberNull\" : null, \"memberNum\" : 3, \"memberStr\" : \"StringJSON\", \"memberBool\" : true , \"memberObj\" : { \"mnum\" : 1, \"mbool\" : false}, \"memberX\" : {}, \"memberArray\" : [33, \"StringTst\",null,{}]";
var jsObjStringParsed = JSON.parse(jsObjString);
var jsObjStringBack = JSON.stringify(jsObjStringParsed);
The object produced by the parse() method and serialized back by stringify() method is the same as:
var jsObjStringParsed =
{
"memberNull" : null,
"memberNum" : 3,
"memberStr" : "StringJSON",
"memberBool" : true ,
"memberObj" :
{
"mnum" : 1,
"mbool" : false
},
"memberX" : {},
"memberArray" :
[
33,
"StringTst",
null,
{}
]
};
JSON.parse(source, reviver)
The JSON.parse method does the the deserialization. It takes the string in JSON format (specified by the argument source) and produces a JScript object or array.
The optional revive argument is a user defined function used for post parse changes. The resulting object or array is traversed recursively, the reviver function is applied to every member. Each member value is replaced with the value returned by the reviver. If the reviver returns null, the object member is deleted. The traversal and the call on reviver are done in postorder. That’s right; every object is ‘revived´ after all its members are ‘revived”.
The reviver is mainly used to recognize the ISO like strings and transform them in Date objects. As of today, JSON format is not round tripping in Date objects because there is no JScript standard Date literal. ES3.1 draft contains an example of how to make up for this issue using a reviver function.
JSON.stringify(value, replacer, space)
This is the serialization method. It takes the object or the array specified by the value argument and produces a string in JSON format. The value object or array is visited recursively and serialized as specified by the JSON format . If value has a method ‘toJSON()’ then this method acts as a first filter. The original value is replaced by value.toJSON(key) and the resulted value is serialized. The argument key is a string. It is the member name, key, when a object member like (key : value) is serialized. For the root object the key is the empty string.
Date.prototype.toJSON() produces a clean string with no characters to escape. It acts as the de facto serializer because stringify() would return the original string unchanged. Date objects are serialized via toJSON() method.
Number.prototype.toJSON() , String.prototype.toJSON() , Boolean.prototype.toJSON() functions return the ValueOf(). They are intended for correct serialization of objects like “ var num = new Number(3.14);”
The optional replacer argument acts as a filter and it is applied recursively. It could be a function or an array.If the replacer is a function then replacer(key,value) is invoked for each object member key:value . For the root object we call replacer(“”,value) . If the replacer is an array, it must be an array of strings. The elements of the array are the names of the members selected for serialization. The order of serialization is the order of the names in the array. An array replacer is ignored when serializing an array.
The optional space argument is about how to format the output text. If it is omitted, the text will be packed without extra whitespace. If it is a number, it specifies the number of spaces to indent at each level. If it is a string (such as '\t' or ' '), it contains the characters used to indent at each level.
How does this affect existing pages?
The ES3.1 proposal for JSON is the form factor used by the popular json2.js. Well, we take over the name JSON. The global JSON object can be overridden. Still, it is not an undefined object anymore. It is the same with introducing new keywords in a language; taking over a name would eventually affect some existing code. The pages that make use of json2.js are unlikely to be affected. With very few exceptions, all these pages will continue to work, only faster.
The pages that define their private implementation of the JSON object could be affected, especially when the private implementation of JSON object is defined by a pattern like “if(!this.JSON) { JSON=…}”. There are two main options to work around this kind of issues:
1. Migrate existing code to use native JSON support
If the private JSON implementation is based on some of version of json2.js the migration should be very simple.
2. Opt out of the native JSON support and continue to use the existing private JSON object
This can be done by renaming or overriding the JSON name. Renaming means to change over all code using the ‘JSON’ name into some different name like ‘MyJSON’. Overriding means to ensure the private JSON definition overrides all code using the native default JSON definition. In most of the cases, just removing the condition “if(!this.JSON)” should do the trick.
Considering the standardization effort in 3.1, using the name ‘JSON’ Is consistent with our desire to be interoperable through well defined interfaces.
There is a lot more about to talk about the native JSON. The parser is not eval() based, it is a standalone implementation. It is the native equivalent of the reference parser provided at JSON support. It is as safe as (https://www.json.org/json_parser.js ) and it is a lot faster. So if you are using eval() or even your own JSON library, consider checking for the native implementation in IE8 to get increased performance and safer operation.
Corneliu Barsan
Senior Developer
JScript team
Comments
Anonymous
September 10, 2008
PingBack from http://www.easycoded.com/native-json-in-ie8/Anonymous
September 10, 2008
All very cool, but what happens when "naughty" JSON is encountered? Is an empty object returned? An error object returned? null returned? Is the "offending" bit removed? As a developer, if something went wrong, I want to know about it. How do I find out what didn't work? or do I?Anonymous
September 10, 2008
Does this interface also require UTF8 encoded input as per RFC4627 (which is a silly requirement imo)?Anonymous
September 10, 2008
> If the reviver returns null, the object member is deleted. You mean undefined, correct? The latest spec says "If it returns undefined then the member is deleted from the result."Anonymous
September 10, 2008
Very Nice! Obviousely, the Native JSON will make things run much more quickly! as Oliver (http://blogs.msdn.com/ie/archive/2008/09/09/what-s-new-for-jscript-for-ie8-beta-2.aspx#8939732) expect. & Hope IE 8 can be more safe on every progress he make!Anonymous
September 10, 2008
I love AJAX. I think that what Microsoft has done is very useful. Just must be tested and to re-write the source code.Anonymous
September 10, 2008
The comment has been removedAnonymous
September 11, 2008
Uno dei post che ho letto con più interesse sul blog del team di prodotto riguarda il supporto nativoAnonymous
September 11, 2008
What the !@#$! .stringify();??? Was JSON.serialize(JSONObj, replaceHandler, delimiter); not available? You guys come up with some of the weirdest APIs I've ever seen. GordonAnonymous
September 11, 2008
Gordon: "stringify" is a standard; it's not Microsoft's name.Anonymous
September 11, 2008
Why are we moving away from evalJson() ?Anonymous
September 11, 2008
@Neil, @Gordon-- Different frameworks have different names for the functions. The names selected for IE's native implementation are based by the ES3.1 proposal, which is in turn based on the most popular/definitive implementation, Douglas Crockford's json2.js. @Tino: RFC4627 covers the wire format for the application/json media type. It's not applicable in this case because the script engine isn't working with a wire format/media type, it's working with a Unicode string. Internally, IE (and I'd imagine most browsers) decode from wire formats into Unicode (UTF16 in our case) and then convert back into encoded formats only as needed. Therefore, your server needs only to return a string in some encoding with the proper encoding specified, then XMLHTTPRequest or XDomainRequest (or whatever) will convert that string into Unicode, and that Unicode string will be handled by the parse() method.Anonymous
September 12, 2008
@steve:” what happens when "naughty" JSON is encountered?”. -- A: If your code doesn’t define the JSON object, a reference to JSON returns the builtin JSON object. You might have a problem only if your code relies on JSON being undefined. If your code defines the JSON object, most probably you override it and you have no problem. If you define your own JSON object conditionally like “if(!this.JSON){ JSON=…}” then the builtin JSON object is visible in your code. An expression like “JSON.encode()” might fail because the builtin object doesn’t have the function “encode”. @paul – right, it is undefined.Anonymous
September 15, 2008
before someone else asks: why won't the IE team look at how other browsers store wire formats? Gecko and KHTML/Webkit are open! Answer: there would be a risk that looking at these code may lead to some form of copyright infringement. Suggestion: why not ask in Gecko and/or Webkit mailing lists how these browsers encode it? Question: UTF16 (2 bytes per character) is a bit... wasteful, isn't it? At the same time, as far as I know, it doesn't cover all characters. Other question: what now happens on UTF-8 encoded documents that get the MS non-standard UTF8 prologue (reversed question mark etc.) ? This may actually cause trouble here if the stream was originally such a document.Anonymous
September 18, 2008
As you might be aware that Internet Explorer Beta 2 was released few weeks back. In this JScript teamAnonymous
October 05, 2008
You've been kicked (a good thing) - Trackback from DotNetKicks.comAnonymous
December 12, 2008
I was testing out some typography with Silverlight and figured I’d try grab some text from WikipediaAnonymous
January 13, 2009
As a Program Manager, I love to write feature specifications (that’s a job description requirement)!Anonymous
January 25, 2009
Обновленный синтаксис Getters/Setters в IE8 RC1 Как программному менеджеру, мне нравится писать спецификацииAnonymous
March 12, 2009
Reports of broken sites are an important part of the feedback the IE team receives from the community.Anonymous
March 16, 2009
    이 글의 제목을 보고 아셨을지 모르겠지만, Internet Explorer 8 은 Beta 2에서 네이티브 JSON 구문해석기능과 serializationAnonymous
March 24, 2009
During Beta1 and Beta2 pre-releases of IE8, we’ve blogged about the performance optimizations done inAnonymous
March 24, 2009
During Beta1 and Beta2 pre-releases of IE8, we’ve blogged about the performance optimizations done inAnonymous
April 09, 2009
In the world of web standards, JavaScript is known as ECMAScript and maintenance of its definition isAnonymous
April 12, 2009
Native JSON parsing and serialization is a new feature to IE8 and Firefox 3.5 and makes evaling a thingAnonymous
April 16, 2009
With Internet Explorer 8 we introduced several new JScript language features including native JSON supportAnonymous
May 08, 2009
I had a great time this week speaking to the Atlanta PHP user group about our new Web Platform gallery