在 HTTP 中有两种 POST 数据的方式:application/x-www-form-urlencoded
和 multipart/form-data
。我知道大多数浏览器只有在使用 multipart/form-data
时才能上传文件。在 API 上下文中使用其中一种编码类型时是否有任何其他指导(不涉及浏览器)?这可能例如基于:
- 数据大小
- 存在非ASCII字符
- 存在于(未编码的)二进制数据上
- 需要传输额外的数据(如文件名)
到目前为止,我基本上没有在网络上找到关于使用不同内容类型的正式指南。
最佳答案
长话短说
总结;如果您要传输二进制(非字母数字)数据(或相当大的负载),请使用 multipart/form-data
。否则,使用 application/x-www-form-urlencoded
。
您提到的 MIME 类型是用户代理(浏览器)必须支持的 HTTP POST 请求的两个 Content-Type
header 。这两种请求的目的都是向服务器发送名称/值对列表。根据传输数据的类型和数量,其中一种方法将比另一种方法更有效。要了解原因,您必须查看每个人在幕后所做的事情。
对于 application/x-www-form-urlencoded
,发送到服务器的 HTTP 消息的主体本质上是一个巨大的查询字符串——名称/值对由与号 (&
),名称和值之间用等号 (=
) 分隔。这方面的一个例子是:
MyVariableOne=ValueOne&MyVariableTwo=ValueTwo
根据specification :
[Reserved and] non-alphanumeric characters are replaced by `%HH', a percent sign and two hexadecimal digits representing the ASCII code of the character
这意味着对于我们的值之一中存在的每个非字母数字字节,将需要三个字节来表示它。对于大型二进制文件,将有效载荷增加三倍将是非常低效的。
这就是 multipart/form-data
的用武之地。使用这种传输名称/值对的方法,每对都表示为 MIME 消息中的“部分”(如其他答案所述) .部分由特定的字符串边界分隔(专门选择以使该边界字符串不会出现在任何“值”有效负载中)。每个部分都有自己的一组 MIME header ,例如 Content-Type
,尤其是 Content-Disposition
,它可以为每个部分指定“名称”。每个名称/值对的值部分是 MIME 消息每个部分的有效负载。 MIME 规范在表示值负载时为我们提供了更多选择——我们可以选择更有效的二进制数据编码以节省带宽(例如 base 64 甚至原始二进制)。
为什么不一直使用multipart/form-data
?对于短的字母数字值(如大多数 Web 表单),添加所有 MIME header 的开销将大大超过更高效的二进制编码所带来的节省。
关于http - application/x-www-form-urlencoded 还是 multipart/form-data?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4007969/