The Accept Header31 May 2011
Years ago, I wrote a book on HTTP. At the time, there wasn't a simple, comprehensive reference for HTTP beyond the various specs, and a really good understanding of HTTP is important if you want to become a really good web developer, which I did. As I was reading and learning everything I could, I was surprised to learn that such a book didn't already exist.
Fast forward to today, and I can barely remember what I wrote. :-) One of the things I always struggle to remember is how to parse the
Accept header. The spec has some examples you can use to refresh your memory, but I've never found RFCs to be a quick read, even when I know what I'm looking for.
Here's an example, the
Accept header my browser sends:
It would be a little easier to read with some spaces:
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8, application/json
Here's a quick reference for how to interpret the
qindicates quality, a measure of preference.
- The default quality is 1.0, the highest preference.
qand the media type it references are delimited by a semicolon.
Here's the breakdown of this particular example:
- It's common for the most preferred type to be listed first, with no quality specified.
- XHTML served as
application/xhtml+xmlis the next type that shares the highest preference. (This site serves XHTML as
text/html. You can read more about this decision in the colophon.)
- XML has a quality of 0.9, indicating a high preference, but not as preferred as HTML and XHTML.
- Asterisks are wildcards, so
*/*matches any type. This is similar to saying anything is fine, but the other types are preferred, because this is given the lowest quality.
- I use JSONovich, which explicitly adds
application/jsonas a supported media type.
It's the support for
application/json that prompted me to blog about this. I've noticed a recent trend that affects sites with APIs when JSON is one of the supported formats. The trend is best shown by example. Here's what I see when I visit Netflix:
Just a few days ago, I would see a web site. Now I see JSON. Pretty crazy, right?
Netflix isn't the first site to make this mistake; it's just the most recent. I experimented a bit to see if I could figure out what they were doing wrong, and I was disappointed with what I found. Would lowering the quality of
application/json all the way to 0.0 make a difference?
Nope, still JSON. The mere presence of the string "json" anywhere in the
Accept header seems to be enough to cause the problem. The
Accept header might be hard to read and parse, but they're not even trying.
I'd love to know why this is becoming more and more common. Is there a broken content negotiation example somewhere that everyone is using? I'm really curious.
I've reported the problem to Netflix via phone and Twitter. Hopefully they'll fix it soon.