内容协商/ Content Nagotiation
HTTP 内容协商/ Content Nagotiation
访问同一个 URI 时,服务器可以返回不同类型的资源。比如在浏览器中访问 http://www.example.com/user
可以是个网页,也可以是个 JSON 接口,甚至可以是张图片等。
具体返回哪种类型,就需要引入内容协商的机制,以达到返回正确资源类型的目的。
内容协商分为服务器主导(server driven)和客户端主导(agent-driven negotiation / reactive negotiation)两种方式。
资源请求及返回过程 -- 图片来自 MDN
服务器主导
服务器主导的内容协商 -- 图片来自 MDN
端上面发送 Accept
请求头,列出期望的 MIME 类型,多种类型用逗号分隔,并且可为每种类型指定相应权值。
示例:
GET /URL HTTP/1.1
Accept: text/*
Accept-Language: en
Accept-Encoding: br, gzip;q=0.8
常用端上发送的请求头有:
Accept
:指定接收的 MIME 类型Accept-Charset
:指定接收的文本编码,比如 utf-8Accept-Encoding
:指定压缩类型,比如br, gzip;q=0.8
Accept-Language
:指定语言
服务器通过返回 Vary
响应头告知客户端哪些 Header 被采用,如果返回的是 *
则表明还有除了请求头之外的其他因素加入到了决策中。该响应头主要为了方便端上面的缓存能够正常工作。
客户端主导
客户端主导的内容协商 -- 图片来自 MDN
当 URI 对应多种资源时,服务器一并返回,由端上自行决定取哪个。
总结
服务器主导其缺点如下:
- 客户端请求头会比较繁多和复杂,增加了带宽成本
- 同时需要服务器去解析和处理相应决策逻辑,增加了服务器成本
- 不够灵活,假如需要增加其他的协商条件,端上需要新增请求头,服务器也需要新增处理逻辑。
- 请求头过多暴露的信息越多,会有安全隐患
客户端主导缺点如下:
- 多了次请求
- HTTP 协议中并未规定用于客户端进行选择的格式,这部分实现不统一