跳至主要内容
短.be

内容协商

客户端与服务器通过 HTTP 头部协商最优内容格式 (语言、数据格式、编码方式) 的机制。

2026年8月24日 · 约 1 分钟阅读

重定向

内容协商 (Content Negotiation) 是 HTTP 通信中客户端 (浏览器) 与服务器协商所请求资源最优表现形式的机制。同一 URL 可以根据用户的语言设置、设备类型和支持的格式返回不同的内容。

内容协商主要通过 HTTP 请求头实现。Accept 头部 (支持的媒体类型:text/html、application/json 等)、Accept-Language 头部 (期望的语言:ja、en-US 等)、Accept-Encoding 头部 (支持的压缩方式:gzip、br 等) 是最常见的协商头部。这些头部都可以附带 q 值来表示优先级,例如 Accept-Encoding: br, gzip;q=0.8 表示首选 br,不支持时接受 gzip。服务器若根据这些头部改变响应内容,就需要在 Vary 头部中列出用于判断的头部名称。漏掉 Vary: Accept-Language 时,缓存或 CDN 会把最先取得的那个语言版本发给后续所有访问者。

多语言网站中的内容协商与短链接密切相关。同一短链接被点击后,可以根据用户浏览器的语言设置重定向到中文页面或英文页面。但从 SEO 角度来看,更推荐为每种语言设置独立的 URL 并通过 hreflang 标签关联。基于内容协商的语言切换可能导致搜索引擎无法正确索引各语言版本。Google 同样建议为每个语言版本准备独立 URL,而不是依据 Cookie 或浏览器设置切换显示,并要求避免把访问者从一个语言版本自动重定向到另一个语言版本,因为这类跳转会让用户与搜索引擎都无法看到全部版本。Google 的抓取程序在请求中不会附带 Accept-Language 头部,因此仅凭该头部切换显示时,被抓取到的只有默认语言版本。根据 IP 推断地区来改变内容的做法同样不建议采用。

API 设计中内容协商同样重要。短链接服务的 API 根据 Accept 头部返回 JSON 或 XML 响应是常见做法。为同一资源准备多种表现形式,可以让调用方选择自己能处理的格式。不过具体选择哪一种表现的算法并未由 HTTP 规范规定,而是交由服务器实现决定。遇到不支持的格式时是返回 406 (Not Acceptable),还是忽略该头部返回默认格式,同样属于实现层面的判断。

内容协商分为服务器驱动型 (服务器根据请求头判断) 和代理驱动型 (服务器提供选项由客户端选择) 两种。HTTP 规范中将前者称为 proactive negotiation,后者称为 reactive negotiation。实际使用中以前者为主,但其代价是根据请求头做出的推断始终带有一定的随意性。后者未能普及,原因在于列出选项的页面格式没有规范定义,导致选择过程无法自动化,而且在取得真正的资源之前会多出一次往返。

分享到 XHatena

这篇文章对您有帮助吗?

相关术语

相关文章

常见问题

应该使用内容协商来自动切换语言吗?
从用户体验角度来看很方便,但 SEO 方面需要注意。搜索引擎可能无法正确索引各语言版本,因此更推荐为每种语言设置独立 URL 并通过 hreflang 标签关联。此外 Accept-Language 只是反映浏览器或系统的设置,并不一定代表访问者当下想读的语言。若要使用自动判断,应仅限于站点的入口页面,并同时提供让访问者自行切换语言的手段。
如何在 API 中实现内容协商?
解析请求的 Accept 头部,如果是 application/json 则返回 JSON,如果是 application/xml 则返回 XML。请求了不支持的格式时并无唯一的处理方式,返回 HTTP 406 (Not Acceptable) 与忽略该头部返回默认格式在规范上都是允许的。由于对调用方而言得到某种响应比毫无响应更易处理,返回默认格式的实现也不少见。用于判断的头部需要以 Vary: Accept 的形式写入响应。
Accept-Language 头部是如何设置的?
基于浏览器的语言设置自动发送。例如中文环境的浏览器会发送类似"Accept-Language: zh-CN,zh;q=0.9,en;q=0.8"的内容,以优先级顺序列出多种语言。

把知识用到真实链接上

免费缩短网址