1. application/json
  2. multipart/form-data
  3. application/x-www-form-urlencoded
  4. text/plain
  5. 参考

常用 POST 数据类型

Content-Type 接受 MIME类型 作为参数值.
传送数据时, 浏览器通过 Content-Type 来告诉服务器发送的数据格式是什么. 发送POST数据时, 常用的 MIME类型 有以下几种:

application/json

Content-Type: application/json 中的 application 表示 POST 数据为 "应用程序特有的格式", json 表示子类为 "JSON".

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var url = 'http://jsonplaceholder.typicode.com/posts';
var xml = new XMLHttpRequest();
xml.open('POST', url);
xml.withCredentials = true;
xml.setRequestHeader('content-type', 'application/json');
xml.onreadystatechange = () => {
if (xml.readyState === 4) {
if (xml.status >= 200 && xml.status < 300) {
console.log(xml.responseText);
}
}
};
var data = { foo: 'bar' };
xml.send(JSON.stringify(data));

2.PNG
1.PNG

rfc4627 json

multipart/form-data

1234.PNG

multipart/form-data 常被用于发送二进制文件,如图片/视频等内容.
Content-Type: multipart/form-data 中的 multipart 表示该数据是多种不同格式数据的组合.

当传递 FormData 对象作为 xml.send 的参数时, 浏览器会自动设置 content-type: multipart/form-data;boundary=----xxx.
content-type 和 Form Data 中的 boundary 字段由浏览器自动生成,便于分割数据.其作用类似于 application/x-www-form-urlencoded 的 '&'.

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var url = 'http://jsonplaceholder.typicode.com/posts';
var xml = new XMLHttpRequest();
xml.open('POST', url);
xml.withCredentials = true;
xml.onreadystatechange = () => {
if (xml.readyState === 4) {
if (xml.status >= 200 && xml.status < 300) {
console.log(xml.responseText);
}
}
};
var data = { foo: 'bar', bar: 'foo' };
var formData = new FormData();
Object.keys(data).forEach(key => formData.append(key, data[key]));
xml.send(formData);

123.PNG
1234.PNG

需注意在传递 FormData 时, 不要手动修改 content-type. 这会使服务器无法正确的分割数据.

1
2
// 错误的设置,不要这样作
xml.setRequestHeader('content-type', 'multipart/form-data; boundary=----xxx');

qer.PNG

RFC 7578 - Returning Values from Forms: multipart/form-data

application/x-www-form-urlencoded

<form> 表单元素默认的数据提交格式.

当传递 URLSearchParams 对象作为 xml.send 的参数时, 浏览器会自动设置 content-type: application/x-www-form-urlencoded.

数据格式 application/x-www-form-urlencoded 是一组用"="号连接的键值对, 键值对间由"&"号分隔. 非字母或数字的字符会被转换为 percent-encoding.

1
2
3
{"foo":"bar"}
-->
foo=bar&bar=foo

如果传入一个数组, 也会作为对象解析.

1
2
3
[1, 2, 3]
-->
0=1&1=2&2=3

非字母/数字的字符会被转换为 percent-encoding, 其行为类似于方法 encodeURIComponent

1
2
3
4
5
{ foo: '测试', bar: 'foo' }
-->
foo=%E6%B5%8B%E8%AF%95&bar=foo

encodeURIComponent('测试') // "%E6%B5%8B%E8%AF%95"

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var url = 'http://jsonplaceholder.typicode.com/posts';
var xml = new XMLHttpRequest();
xml.open('POST', url);
xml.withCredentials = true;
// xml.setRequestHeader('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
xml.onreadystatechange = () => {
if (xml.readyState === 4) {
if (xml.status >= 200 && xml.status < 300) {
console.log(xml.responseText);
}
}
};
var data = { foo: 'bar', bar: 'foo' };
var params = new URLSearchParams();
Object.keys(data).forEach(key => params.append(key, data[key]));
xml.send(params);

1.PNG
2.PNG

注意: ie不支持 URLSearchParams

RFC 1866 - Hypertext Markup Language - 2.0

text/plain

当传递 对象/ 基本类型作为 xml.send 的参数,且没有手动设置 content-type 时,浏览器会自动将 content-type 设置为 text/plain.

发送方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
var url = 'http://jsonplaceholder.typicode.com/posts';
var xml = new XMLHttpRequest();
xml.open('POST', url);
xml.withCredentials = true;
xml.onreadystatechange = () => {
if (xml.readyState === 4) {
if (xml.status >= 200 && xml.status < 300) {
console.log(xml.responseText);
}
}
};
var data = { foo: 'bar' };
xml.send(data);

参考

四种常见的 POST 提交数据方式 | JerryQu 的小站
https://web.archive.org/web/20140613004726/http://laichendong.com/rfc4627-zh_cn/
http - application/x-www-form-urlencoded or multipart/form-data? - Stack Overflow