Content negotiation are mechanisms defined as a part of HTTP that make it possible to serve different versions of a document (or more generally, representations of a resource) at the same URI, so that user agents can specify which version fit their capabilities the best. One classical use of this mechanism is to serve an image in GIF or PNG format, so that a browser that cannot display PNG images (e.g. MS Internet Explorer 4) will be served the GIF version.
HTTP provides for several different content negotiation mechanisms including: server-driven (or proactive), agent-driven (or reactive), transparent, and/or hybrid combinations thereof.
So, a resource may be available in several different representations. For example, it might be available in different languages or different media types, or some other combinations. One way of selecting the most appropriate choice is to give the user an index page, and let them select, however it is often possible to automate the choice based on some selection criteria.
Server-driven or proactive content negotiation is performed by algorithms on the server which choose among the possible variant representations. This is commonly performed based an user-agent provided acceptance criteria.
To summarize how this works, when a user agent submits a request to a server, the user agent informs the server what media types it understands with ratings of how well it understands them. More precisely, the user agent provides an
Accept HTTP header that lists acceptable media types and associated quality factors. The server is then able to supply the version of the resource that best fits the user agent's needs.
This works because browsers can send information as part of each request about the representations they prefer. For example, a browser could indicate that it would like to see information in German, if possible, else English will do. Browsers indicate their preferences by headers in the request. To request only German representations, the browser would send:
Note that this preference will only be applied when there is a choice of representations and they vary by language.
As an example of a more complex request, this browser has been configured to accept German and English, but prefer German, and to accept various media types, preferring HTML over plain text or other text types, and preferring GIF or JPEG over other media types, but also allowing any other media type as a last resort:
Accept-Language: de; q=1.0, en; q=0.5 Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1
In addition to server-driven content negotiation by content type and by language, there is an extension to use content negotiation to retrieve prior version in time with the
RFC 7231 does not specify how to resolve trade-offs (such as, in the above example, choosing between an HTML page in English and a GIF image in German).
Agent-driven or reactive content negotiation is performed by algorithms in the user-agent which choose among the possible variant representations. This is commonly performed based a server provided list of representations and metadata about them.
User-agents can request data in specified formats from web services or web APIs, such as application/json or application/xml.
- Memento: Adding Time to the Web. Mementoweb.org. Retrieved on 2013-09-08.
- RFC 7231 — Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content – (Section 5.3: Content Negotiation)
- RFC 2295 — Transparent Content Negotiation in HTTP
- RFC 2296 — HTTP Remote Variant Selection Algorithm -- RVSA/1.0
- Apache Content Negotiation
- Open source PHP content negotiation library (supports wildcards and q values)
- Discussion about XHTML serving with content negotiation and browser concerns requiring this