application/x-www-form-urlencoded 还是 multipart/form-data?

application/x-www-form-urlencoded 还是 multipart/form-data?

技术背景

在 HTTP POST 请求中,application/x-www-form-urlencodedmultipart/form-data 是用户代理(如浏览器)必须支持的两种 Content-Type 头部。这两种请求类型的目的都是向服务器发送一组名值对,不过根据传输数据的类型和数量,其中一种方法会比另一种更高效。

实现步骤

application/x-www-form-urlencoded

  • HTTP 消息体本质上是一个巨大的查询字符串,名值对之间用 & 分隔,名称和值之间用 = 分隔。
  • 非字母数字字符会被替换为 %HHHH 是代表字符 ASCII 码的两位十六进制数字)。
  • 示例:MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

multipart/form-data

  • 每个名值对在 MIME 消息中表示为一个“部分”,部分之间由特定的字符串边界分隔。
  • 每个部分都有自己的 MIME 头部,如 Content-TypeContent-Disposition,后者可以为每个部分命名。
  • 名值对的值部分是 MIME 消息每个部分的有效负载,可以选择更高效的二进制数据编码方式(如 Base64 或原始二进制)以节省带宽。

核心代码

使用 application/x-www-form-urlencoded 的示例(JavaScript)

1
2
3
4
5
6
7
8
9
10
11
12
13
const formData = {
MyVariableOne: 'ValueOne',
MyVariableTwo: 'ValueTwo'
};
const queryString = Object.keys(formData).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(formData[key])}`).join('&');

fetch('your-url', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: queryString
});

使用 multipart/form-data 的示例(JavaScript)

1
2
3
4
5
6
7
8
const formData = new FormData();
formData.append('MyVariableOne', 'ValueOne');
formData.append('MyVariableTwo', 'ValueTwo');

fetch('your-url', {
method: 'POST',
body: formData
});

最佳实践

  • 如果要传输二进制(非字母数字)数据或大量有效负载,使用 multipart/form-data
  • 如果是短字母数字值(如大多数 Web 表单),使用 application/x-www-form-urlencoded
  • 当使用 multipart/form-data 时,选择的边界字符不能出现在编码输出中,例如可以使用 Base64 编码,并选择一个不会出现在 Base64 输出中的 7 位 ASCII 字符串作为边界。

常见问题

application/x-www-form-urlencoded 的问题

对于大的二进制文件,由于每个非字母数字字节需要用三个字节来表示,会导致有效负载大幅增加,效率低下。

multipart/form-data 的问题

边界分隔符不能出现在文件数据中,否则服务器可能会在错误的位置找到边界,导致文件截断或 POST 请求失败。因此,需要选择合适的编码和边界。

其他问题

  • 在使用 Content-Type=x-www-urlencoded-form 时,在 ASP.NET Core 2+ 中不要使用 FormDataCollection 作为参数,应使用 IFormCollection
  • 当响应的 contentTypeapplication/x-www-form-urlencoded 但实际包含 JSON 数据时,在 Django 中访问 request.data 可能无法正确转换,需要访问 request.body

application/x-www-form-urlencoded 还是 multipart/form-data?
https://119291.xyz/posts/application-x-www-form-urlencoded-or-multipart-form-data/
作者
ww
发布于
2025年5月28日
许可协议