With so many discussions about JSON going on lately (like XML Has Too Many Architecture Astronauts from last week) I’m tired of seeing people suggest that JSON is great because you can just eval( ) it. This immediately makes me nervous. Executing remote code that you don’t control just doesn’t strike me as a good idea. You can reduce the risk this brings by running it through the Javascript JSON parser.
Even better than that though is that you don’t have to use eval( ) at all to make use of JSON. By using callback functions you can avoid using eval( ) completely. Here’s an example of how this works using the Yahoo Time Service API (some lines wrapped for easy reading):
<script type="text/javascript"> function handleJson(json) { alert("Timestamp: " + json.Result.Timestamp); } </script> <script type="text/javascript" src="http://developer.yahooapis.com/TimeService/V1/getTime? appid=YahooDemo&output=json&callback=handleJson"> </script>
The code from the Yahoo! API looks like:
handleJson({"Result":{"Timestamp":1168227638}});
So if you’ve run away from looking closely from JSON because all this talk of eval( )’ing remote code then come back and look at callback functions.
While writing this I started learning more about how eval( ) works in JSON. Tom Insam has a great blog post on Javascript eval( ). It turns out that eval( ) isn’t a function at all, but an object method. On top of that it is limited to the context that it is used in. Just incase Tom’s post disappears one day I’ve included his examples.
Limit eval( )’ed code to a specific object:
var code = "var a = 1"; eval(code); // a is now '1'. var obj = new Object(); obj.eval(code); // obj.a is now 1
Limit eval( )’ed code to a specific function:
var a = 2; function foo() { eval(code); // a is 1, but scoped inside the function } foo(); // a is back to being 2 here
Get eval( )’ed code into the global scope from inside a function:
var a = 2; var global = this; function foo() { global.eval(code); // a is 1 globally now } foo(); // a is now 1
So even if you don’t want to use eval( ) for remote scripts, now you’ve got a few tricks for using eval( ) in your own scripts.
3 replies on “JSON Does Not Require eval( )”
Your website doesn’t define a default text color, but sets the bg color in many places. As my default text color is white, this results in white-on-white text in many places. Please add ‘color: #000000;’ to the body-element (or whatever-the-white-areas-are) in your css. You shouldn’t trust the user to have sensible defaults 🙂
Sorry about that, I’ve changed it now.
It’s neat that the Yahoo API gives you this shortcut, but I don’t see why it makes you any less nervous than using eval() directly. By putting a Yahoo URL in your script src=”…” attribute, you’re still blindly executing whatever code Yahoo decide to send back, and trusting them not to do anything evil.