I don’t want anyone take this the wrong way. I am having a torrid affair with JSON. It is so much simpler to parse than XML, and is an all around exceptional way to represent data. I have one caveat though, and that is “JSON with Padding” or “JSONP” as it goes by.
While building this site I was trying to bring in images from my Flickr account, as you may have noticed. Building the module in PHP, I basically ran file_get_contents on the feeds url and passed that directly into json_decode. On print_r’ing the results, it was null. It had failed. As a test I echoed the result of the file_get_contents to see what was up. It was succeeding at retrieving the feed, and at a glance it looked like JSON, yet it was failing to parse. I knew something was up.
Here is an example result set:
jsonFlickrFeed({
"title": "Uploads from donatj",
"link": "http://www.flickr.com/photos/donatj/",
"description": "",
"modified": "2009-05-31T08:24:46Z",
"generator": "http://www.flickr.com/",
"items": [
{
"title": "STP81353",
"link": "http://www.flickr.com/photos/donatj/3581174864/",
"media": {"m":"http://farm4.static.flickr.com/3568/3581174864_be1a44764e_m.jpg"},
"date_taken": "2009-03-30T19:10:34-08:00",
"description": "<p><a href=\"http://www.flickr.com/people/donatj/\">donatj<\/a> posted a photo:<\/p> <p><a href=\"http://www.flickr.com/
photos/donatj/3581174864/\" title=\"STP81353\"><img src=\"http://farm4.static.flickr.com/3568/3581174864_be1a44764e_m.jpg\" width=\"180\" height=\"240\" alt=\"S
TP81353\" /><\/a><\/p> ",
"published": "2009-05-31T08:24:46Z",
"author": "nobody@flickr.com (donatj)",
"author_id": "30444376@N08",
"tags": ""
}
]
})On further examination I noticed, as you should have noted, the data is wrapped in a function. My first thought was that this violates the JSON Specification, so I immediately tweeted about how silly it was for Flickr to have an invalid JSON feed when their parent company Yahoo employs Douglas Crockford, the creator of JSON. I soon received a response from a colleague informing me that this was JSONP. He explained what it was, and how to use it in jQuery.
It basically comes down to this: XMLHttpRequest will not, for cross site scripting protection, work across domains. Therefore, JSON cannot be directly retrieved nor parsed via JavaScript across domains.
This is where JSONP comes in. JSONP is essentially a regular JSON result set wrapped in a function. Rather than using XMLHttpRequest to retrieve the document, you dynamically attach a script tag to the page pointing the the JSONP document, which evokes a function call passing your JSON object to whatever function the JSONP is set to pass the data to, forgoing the need to eval anything.
I have a number of criticisms of this approach.
JSONP is in many cases an unsafe practice, and more over its just evil. It is a necessary evil in some cases, but evil none the less.
There is at least one safe alternative to JSONP, and I’m willing to wager more. The simplest solution provided you have access to server side code is to download, sanitize, optionally cache, and finally pass locally any remote JSON to the client rather than having the clients machine directly load the feed. Yes, this is added overhead on your side, bur for much added security.
If nothing else, it is up to you to weigh the risks and benefits before blindly using JSONP.