Is this a good way of Parsing JSON?
Im looking at another developers code that parses some JSON. I cant really see how it works or if its a good idea...
hmlPlaylist.prototype.loadVideos_callback = function (data) {
var jsonData = '';
var jsonError = false;
try {
jsonData = eval("(" + data + ")");
} catch (jError) {
jsonError = true;
}
if (!jsonError) {
if (jsonData.playlists.length > 0) {
this.buildPlaylistList(jsonData.playlists);
}
if (jsonData.videos.length > 0) {
this.buildVideoList(jsonData.videos);
this.bindVideoNavs();
}
}
else {
//开发者_如何学C no json returned, don't do anything
}
};
Its the line
jsonData = eval("(" + data + ")");
That gets me. What does this do to the data? I thought you had to use an extarnal class library to parse JSON data?
I can see later on that he iterates the collection like this:
for (var i = 0; i < playlistCount; i++) {
var p = playlists[i];
So is this really a good way of going through JSON?
Most modern browsers support a native JSON.parse
method that does exactly this. If you are targeting a browser that does not, you can use Douglas Crockford's implementation provided here (scroll to the bottom).
In any case, do not use eval
if you can at all avoid it.
Update (regarding eval
):
As JSON.org states:
JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.
What does this mean in practice? Well, it means that any valid JSON object is also valid JS code (in technical terms: it's a valid JS expression that evaluates to an object literal). Therefore, you can paste JSON into a file and tell e.g. your browser to load it as JavaScript and it will do so without any error or warning (of course the "JavaScript" won't actually do anything because it's just the representation of an object and not procedural code).
Since we established that JSON can be interpreted as JavaScript, it can also be passed to eval
. Let's see what the MDC has to say about eval
:
The argument of the eval function is a string. If the string represents an expression, eval evaluates the expression.
...
Parsing JSON (converting strings to JavaScript objects)
If the string you're calling
eval()
on contains data (for example, an array:"[1, 2, 3]"
), as opposed to code, you should consider switching to JSON, which allows the string to use a subset of JavaScript syntax to represent data.
The above is perhaps not the best explanation, but it does say what happens: JSON can be seen as a JS expression. eval
takes a string representing a JS expression (in this case, a string containing JSON), evaluates it, and returns the result. It's like a mini-compiler that you can feed code to at runtime, and it will run the code for you and return the result. In this case, the result will be a JS object (as already mentioned, JSON is a valid JS expression that represents an object).
So if you have
var json = '{"foo": "bar", "answer": 42}';
var object1 = eval(json);
var object2 = { foo: "bar", answer: 42 };
Then object1
and object2
will be two different but identical objects.
JSON.parse(stringOfJson)
is the best way to parse json. If you are using jquery, then you can tell $.ajax
that you are expected json back, and it will parse it for you, with the dataType: 'json'
configuration option
Don't do that. Do this: https://github.com/douglascrockford/JSON-js
One of the best recommended JSON parsers for Javascript.
JSON is java script code.
jsonData = eval("(" + data + ")");
The eval()
function is executing the java script code and return the result (the object). You can find some information about eval
here.
The problem is, the eval
function can also execute normal java script code, it's insecure. Use JSON.parse(data)
instead.
eval
just runs whatever string is supplied to it as though it were code. If you supply it JSON as a string, it evaluates the string as code, which then produces a JSON object. eval
is legitimate for parsing JSON, although the argument for that has gotten considerably weaker these days as better methods exist (JSON.parse
, jQuery's $.ajax
with a "json"
datatype
or $.getJSON
).
For an example of the argument eval
accepts and what it produces:
var a = {foo: [0, 1], bar: {baz: 2}};
var b = JSON.stringify(a);
alert(b); // alerts '{"foo":[0,1],"bar":{"baz":2}}'
var c = eval("(" + b + ")");
alert(c.foo); // alerts '0,1'
alert(c.bar.baz); // alerts '2'
As for the safety of eval
, as long as it can only accept well-formed JSON from your server that's not subject to user input, the risks are fairly minimal. The risk, FWIW, is that some user supplies JS code as a string that would inject a script, which could then be used to gather sensitive information on other users who visit the page. JSON.parse
-- unless you're eval
ing some of its contents afterwards -- wouldn't have this risk.
精彩评论