3

对于不是由 HTML 表单发送的请求,HTTP 是否将请求的 Content-Type 限制为 application/x-www-form-urlencoded 以进行非文件上传,或者该 MIME 类型是否“正确”/标准/在任何其他语义上有意义方式?

例如,PHP 自动将内容解析为 $_POST,这似乎表明 x-www-form-urlencoded 是服务器期望的。另一方面,我可以使用 Ajax 在 HTTP 请求内容中发送一个 JSON 对象,并将 Content-Type 设置为 application/json。至少一些服务器技术(例如 WSGI)不会尝试解析它,而是以原始形式将其提供给脚本。

我应该在 RESTful API 中的 POST 和 PUT 请求中使用哪种 MIME 类型,以确保符合 HTTP 的所有服务器实现?我忽略了诸如 SOAP 和 JSON-RPC 之类的技术,因为它们通过 HTTP 隧道协议,而不是按预期使用 HTTP。

4

1 回答 1

5

简答

您应该指定最能描述 HTTP 消息实体主体的任何内容类型。

长答案

例如,PHP 自动将内容解析为 $_POST,这似乎表明 x-www-form-urlencoded 是服务器期望的。

服务器没有“期待” x-www-form-urlencoded。PHP - 为了使开发人员的生活更简单 -$_POST当且仅当Content-Type: x-www-form-urlencoded实体主体实际上是一个 urlencoded 键值字符串时,才会将表单编码的实体主体解析为超全局。对于到达的消息,遵循类似的过程Content-Type: multipart/form-data来生成$_FILES数组。虽然很有帮助,但不幸的是,这些超全局变量被命名了,它们混淆了实际 HTTP 事务中真正发生的事情。

我应该在 RESTful API 中的 POST 和 PUT 请求中使用哪种 MIME 类型,以确保符合 HTTP 的所有服务器实现?

您应该指定最能描述 HTTP 消息实体主体的任何内容类型。始终遵守官方的 HTTP 规范——如果你这样做,你就不会出错。来自RFC 2616 Sec 7.2.1(强调添加):

任何包含实体主体的 HTTP/1.1 消息都应该包含定义该主体的媒体类型的 Content-Type 头字段。当且仅当媒体类型不是由 Content-Type 字段给出时,接收者可以尝试通过检查其内容和/或用于识别资源的 URI 的名称扩展来猜测媒体类型。如果媒体类型仍然未知,接收者应该将其视为类型“application/octet-stream”。

任何主流服务器技术都会遵守这些规则。深思熟虑的 Web 应用程序不会信任您的Content-Type标头,因为它可能正确也可能不正确。消息的发起者可以随意发送完全虚假的值。通常Content-Type检查头部作为初步验证措施,但通过解析实际数据进一步验证内容。例如,如果您将 JSON 数据放入 REST 服务,则端点可能首先检查以确保您已发送Content-Type: application/json,然后实际解析消息的实体主体以确保它确实是有效的 JSON。

于 2012-08-25T17:32:43.667 回答