Flickr, JavaScript, DOM, and JSON

So, I wanted, like the rest of the internet, to have my most recent photographs appear in a bar at the top of my homepage. Normally, this is easy. However, I invented the following requirements for myself, just to make things more difficult:

Note that this third requirement makes no sense, as I run my own webserver and can use PHP if I feel like it. But I'd set out the challenge for myself, and wanted to meet it.

The first solution I investigated is the flickr badge creator. However, the code generated here is noncompliant with just about any spec, and rather difficult to edit. Veerle has instructions for a “W3C-Compliant” Flickr badge, which is nice, but still full of document.write() and the like.

A perfectly acceptable solution, which meets all of the requirements above, though, is provided by Patrick Quinn-Graham's DOM Flickr Badge. There are actually no problems with this solution, which relies on a PHP script running on Quinn-Graham's server, which he makes available for public use. It works quite well, and the first version of my Flickr badge used this service. But, still, I didn't really want to be relying on some random external service, and furthermore, there are some performance issues raised by always adding an additional layer of indirection. Wouldn't it be nice if my Flickr badge relied only on, well, Flickr?

Not knowing all that much about web programming, I expected that I would be able to get all AJAX-y and call the well-documented Flickr API from JavaScript code. However, the XMLHttpRequest object can not talk to servers other than that from which the script itself came. This is sensible enough from a security perspective, but a bit annoying for actually getting things done. There is a loophole in the JavaScript security model, though. One cannot write scripts which access data on a remote server, but one can request the execution of code from arbitrary places on the Internet. The remote code and local code can then interact through global variables, calling each other's functions, and the like. Presumably this is somehow a defensible security practice, but I haven't figured out exactly why that should be the case.

But what remote code to include? The Flickr JavaScript bagde, as mentioned above, isn't what I want. However, there is a little-publicized alternative. Flickr offers feeds in many formats, including not only the usual RSS and friends but also JSON. JSON is a well-defined subset of JavaScript which can be used for sending objects across the Internet. The version emitted by Flickr will, if you retrieve it with a <script> tag, call a JavaScript function named jsonFlickrFeed() with an object containing some useful information about your Flickr photos. Ah, progress!

So, the way to proceed is:

  1. Write some JavaScript with a function called jsonFlickrFeed() which takes one argument, an array of object representing photographs.
  2. At some appropriate point, have a <script> tag poiting to the Flickr feed of your choice, making sure to give the format=json parameter.

One problem is that nowhere in the JSON object can one get a reference to the nice 75×75 square image which everyone puts on their websites. However, with a bit of regular expression hackery, one can extract the URL for the “small” size image. Then, replacing the trailing _m.jpg with _s.jpg will give the square image. This technique comes from FlickrFont.

My (current) final code is in flickr-dom.js, and you can see the result on my homepage. Note that I've kept the callback code used by Patrick Quinn-Graham's script.

Let me know if you have any questions or suggestions.