Http 应用程序/x-www-form-urlencoded还是多部分/表单数据?

Http 应用程序/x-www-form-urlencoded还是多部分/表单数据?,http,post,http-headers,Http,Post,Http Headers,在HTTP中,发布数据有两种方式:application/x-www-form-urlencoded和multipart/formdata。我知道大多数浏览器只有在使用多部分/表单数据时才能上传文件。在API上下文中何时使用其中一种编码类型(不涉及浏览器),是否有其他指导?例如,这可能基于: 数据大小 非ASCII字符的存在性 存在于(未编码)二进制数据上 需要传输额外数据(如文件名) 到目前为止,我基本上没有在网上找到关于使用不同内容类型的正式指导。我不认为HTTP仅限于以多部分或x-ww

在HTTP中,发布数据有两种方式:
application/x-www-form-urlencoded
multipart/formdata
。我知道大多数浏览器只有在使用
多部分/表单数据
时才能上传文件。在API上下文中何时使用其中一种编码类型(不涉及浏览器),是否有其他指导?例如,这可能基于:

  • 数据大小
  • 非ASCII字符的存在性
  • 存在于(未编码)二进制数据上
  • 需要传输额外数据(如文件名)

到目前为止,我基本上没有在网上找到关于使用不同内容类型的正式指导。

我不认为HTTP仅限于以多部分或x-www-form-urlencoded方式发布。与HTTP POST方法正交(您可以填充适合您的MIME类型)。典型的基于HTML表示的Web应用程序也是如此(例如,json负载在为ajax请求传输负载时变得非常流行)

关于HTTP上的Restful API,我接触过的最流行的内容类型是application/xml和application/json

应用程序/xml:

  • 数据大小:XML非常冗长,但在使用压缩时通常不是问题,并且认为写访问情况(例如通过POST或PUT)比读访问更为罕见(在许多情况下我同意Manuel所说的很多。事实上,他的评论指的是这个url

    ……其中指出:

    内容类型
    “application/x-www-form-urlencoded”是 发送大型邮件效率低下 二进制数据或文本的数量 包含非ASCII字符 内容类型“多部分/表单数据” 应用于提交表单 包含文件、非ASCII数据、, 和二进制数据

    然而,对我来说,这将归结为工具/框架支持

    • 你喜欢什么工具和框架 期望您的API用户正在构建 他们的应用程序是否与
    • 他们有吗 他们可以使用的框架或组件 那就是赞成一种方法胜过另一种方法 其他的
    如果你对你的用户以及他们将如何使用你的API有一个清晰的概念,那么这将帮助你做出决定。如果你让你的API用户难以上传文件,那么他们就会离开,当然你会花很多时间来支持他们

    其次是您编写API的工具支持,以及您可以多么容易地适应一种上传机制而不是另一种上传机制。

    TL;DR


    概述;如果您有二进制(非字母数字)数据(或较大的有效负载)要传输,请使用
    多部分/表单数据
    。否则,请使用
    应用程序/x-www-form-urlencoded


    您提到的MIME类型是用户代理(浏览器)发出的HTTP POST请求的两个
    内容类型
    头必须支持。这两种类型的请求的目的都是向服务器发送名称/值对列表。根据传输的数据的类型和数量,其中一种方法将比另一种方法更有效。要了解原因,您必须查看每种方法在幕后做了什么


    对于
    application/x-www-form-urlencoded
    ,发送到服务器的HTTP消息主体实质上是一个巨大的查询字符串——名称/值对由符号(
    &
    )分隔,名称与值由等号(
    =
    )分隔。这方面的一个例子是:

    MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

    根据报告:

    [保留字符和]非字母数字字符替换为`%HH',一个百分号和两个十六进制数字,表示字符的ASCII码

    这意味着,对于存在于其中一个值中的每个非字母数字字节,将需要三个字节来表示它。对于大型二进制文件,将负载增加三倍将是非常低效的

    这就是
    multipart/form data
    的用武之地。通过这种传输名称/值对的方法,每对都在MIME消息中表示为一个“部分”(如其他答案所述)。部分由一个特定的字符串边界分隔(特别选择,以便此边界字符串不会出现在任何“值”有效负载中)。每个部分都有自己的MIME头集,如
    内容类型
    ,特别是
    内容配置
    ,它可以为每个部分提供“名称”每个名称/值对的值部分是MIME消息每个部分的有效负载。MIME规范在表示值有效负载时为我们提供了更多选项——我们可以选择更有效的二进制数据编码来节省带宽(例如,base 64或甚至原始二进制)


    为什么不一直使用
    multipart/form data
    ?对于短字母数字值(像大多数web表单一样),添加所有MIME头的开销将大大超过更高效的二进制编码所节省的成本。

    请至少阅读此处的第一段!

    我知道这已经晚了3年,但Matt(已接受)的回答不完整,最终会给您带来麻烦。这里的关键是,如果您选择使用
    多部分/表单数据
    ,则边界不得出现在服务器最终接收的文件数据中


    这对于
    应用程序/x-www-form-urlencoded
    来说不是问题,因为没有边界。
    x-www-form-urlencoded
    也可以始终处理二进制数据,只需将一个任意字节转换为三个
    7BIT
    字节。效率低下,但它可以工作(请注意,关于无法发送文件名和二进制数据的注释是不正确的;您只需将其作为另一个键/值对发送)

    multipart/form data
    的问题在于,文件数据中不能存在边界分隔符(请参阅;第5.2节还包括一个相当蹩脚的excu)
    POST /images
    Content-type: multipart/mixed; boundary="xxxx" 
    ... multipart data
    
    201 Created
    Location: http://imageserver.org/../foo.jpg
    <main-resource>
     ...
     <link href="http://imageserver.org/../foo.jpg"/>
    </main-resource>
     public IActionResult Search([FromForm]IFormCollection type)
        {
            return Ok();
        }