judofyr / timeless

A mixture of a blog, wiki and CMS, inspired by Christoffer Sawicki's Termos and James Adam's Vanilla.rb
http://timeless.judofyr.net/
Other
115 stars 14 forks source link

JSONP is not JSON #58

Closed tbroyer closed 12 years ago

tbroyer commented 13 years ago

JSON might not be a subset of JavaScript (and maybe not, if JavaScript means ES5 and not ES3, as someone else already pointed in issue #57) but JSONP is not related in any way with JSON, it's plain JavaScript. There's no guarantee that it'll consist only of a function call, there's no guarantee that it'll use the JavaScript object (or array) literal notation.

I mean, this is a valid "JSONP" response (adapted from Wikipedia's example):

var res = { Name: "Cheeso" };   // variable + unquoted property name
res.Id = parseInt("1823");      // assignment + function call
res["Rank"] = 7;                // another kind of assignment
console.log("received: ", res); // method call
parseResponse(res);
judofyr commented 13 years ago

Yes, I agree with you. How exactly do you suggest I should update the article?

Anyway, the point is that many believe that callback(JSON_DATA) is always valid JavaScript (because we've heard that JSON is subset of JavaScript), but that's in fact not true.

tbroyer commented 13 years ago

Well, first, enlighten the fact that JSONP, despite its name, is JavaScript, and not JSON. So if you have a JSON string and want to use it as a JavaScript object literal, you'll have to escape the offending characters (provided the JSON is "valid", it's then guaranteed to be "valid JavaScript" too, with no character escapes outside string literals). In other words, the issue is not with "we're sending JSON that's parsed by a JavaScript engine", but rather "we're sending JavaScript so we better make sure it's parseable". All in all, this is not much different than sending an XHTML snippet as text/html (interpreted as HTML, and not XML, by a browser): you have to make sure you don't use ' because there's no such thing in HTML (well, a few gotchas re start-end tags)

judofyr commented 13 years ago

(provided the JSON is "valid", it's then guaranteed to be "valid JavaScript" too, with no character escapes outside string literals).

That's exactly why I wrote the article: This is not true. A valid JSON string can contain a literal U+2028 or U+2029. Such a string is not valid JavaScript and will not be parsed by a browser.

tbroyer commented 13 years ago

If you quote out of context, of course! The "then" in "it's then guaranteed to be valid Javascript" is to be understood as "after you "escape the offending characters". What I meant here is that because U+2028 and U+2029 can only be in string literals in JSON, blindly escaping them all to \u2028 and \u2029 won't produce invalid JavaScript (with, say, something like callback(\u2028{"foo": \u2029 "bar" }); that cannot happen). In other words: if your JSON was "valid JSON", it cannot produce invalid JavaScript after replacing U+2028 and U+2029 with \u2028 and \u2029.

judofyr commented 12 years ago

In other words: if your JSON was "valid JSON", it cannot produce invalid JavaScript after replacing U+2028 and U+2029 with \u2028 and \u2029.

Exactly. That's why it's (luckily) an easy fix :-)