Content negotiation, AJAX, and APIs

I thought I was being so clever when I put a content-negotiated API into TradeUps.net, my web development playground. To put it simply, a page can return the same information in different formats, depending upon the HTTP Accept: header. For example, this profile page (view only in Firefox for now) responds to a standard browser request with an HTML document, but returns JSON when it sees Accept: application/json as a header. In this case, a script on the page calls the same URL (/user/admin) again to get the map data in javascript-friendly format. That's where the weirdness starts.

View Source on that page — you should see JSON instead of HTML. That's because Firefox is ignoring the Vary: Accept response header and overwriting the page cache with the JSON response. Even worse, if you try to save the page to your hard drive, you'll get the JSON there as well. (I have yet to see what IE does because IE7 sends a strange Accept header some of the time, and I haven't put in a fix on the server yet.)

(Sidenote: People could use this flaw as a way of hiding their source code. Just make an AJAX call with Accept: null/void and return an empty response. This won't protect the source if javascript is disabled or if the source is accessed through the DOM, but it will prevent casual inspection.)

I really want to use content negotiation for my API, but this behavior is a potential blocker. Any ideas?


Responses: 2 so far

  1. dret says:

    when i do a "view source" in firefox, the /user/admin page works fine (i use firefox 2.0.0.7 on windows), i do see html. apart from the weirdness, were there any functional problems with your approach? i think using content negotiation for deciding between representations is the way to go (even though i was thinking about xml vs. json), so i was googling for it and found your report...

  2. Tim McCormack says:

    That's the only problem I had. It's *super annoying* when I try to use certain web development tools, though.