← 中文资源

简体中文版本

内容协商

内容协商通过 Accept 等请求头让客户端表达媒体类型、语言和编码偏好,由服务器选择并标注响应表示。

阅读英文原文

工作原理

请求可以携带多个偏好头:Accept 列出媒体类型,Accept-Language 列出语言,Accept-Encoding 列出压缩方案。每个条目可带 0 到 1 的质量值,供服务器排序。服务器选择最佳可用表示,用匹配的 Content-Type 或 Content-Language 返回,并添加 Vary,让缓存按影响选择的请求头建立键。若没有可接受的表示,正确响应是 406 Not Acceptable。

GET /docs/guide HTTP/1.1
Accept: text/html;q=1.0, application/json;q=0.8
Accept-Language: fr-CA, en;q=0.7
Accept-Encoding: br, gzip

服务器也可以忽略偏好返回默认表示,但必须如实标注。

何时使用与取舍

内容协商适合内容平台、国际化站点,以及支持多种媒体类型或版本的 API。它让每个资源保持一个 URL,同时允许客户端选择格式,对可访问性、带宽和本地化都有价值。

代价是每个协商维度都会成倍增加缓存变体。Vary: Accept, Accept-Language, Accept-Encoding 可能严重碎片化 CDN 缓存,规范化请求头或使用独立 URL 往往更高效。质量值容易被误读,真正发送精确偏好的客户端也很少。调试时必须检查请求头,而不只是路径。

示例与误解

常见错误是把 Accept 当成强制要求。客户端请求 XML 而服务器只有 JSON 时,只有在客户端没有禁止 JSON 的情况下返回 JSON 才合法,否则应返回 406。另一个错误是通过 Accept-Language 切换语言,却只缓存一份变体给所有用户。相关概念:HTTP 缓存、API 版本管理、缓存失效。