The Accept Header
31 May 2011Years 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:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
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 Accept
header:
- The
q
indicates quality, a measure of preference. - The default quality is 1.0, the highest preference.
- Each
q
and the media type it references are delimited by a semicolon.
Here's the breakdown of this particular example:
text/html
- It's common for the most preferred type to be listed first, with no quality specified.
application/xhtml+xml
- XHTML served as
application/xhtml+xml
is the next type that shares the highest preference. (This site serves XHTML astext/html
. You can read more about this decision in the colophon.) application/xml;q=0.9
- XML has a quality of 0.9, indicating a high preference, but not as preferred as HTML and XHTML.
*/*;q=0.8
- 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. application/json
- I use JSONovich, which explicitly adds
application/json
as 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?
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json;q=0.0
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.