post 三种提交数据方式

三种 Post 提交数据方式

根据 HTTP 协议规范,一般把 HTTP 请求分为三个部分:状态行、请求头、内容主体。

协议规定 Post 请求的数据必须放到内容主体中,但并未规定数据的格式。换句话说,只要请求满足上面的格式,服务端能够正常解析数据即可。

服务端通常根据请求头(headers)中的 content-type 字段来获取内容主体的格式,然后再对内容进行解析。常见的编码格式(content-type)有如下几种:

application/x-www-form-urlencoded

application/x-www-form-urlencoded 是最常见的,也是默认的 Post 数据方式,请求信息与下面请求类似:

Content-Type 被指定为 application/x-www-form-urlencoded;提交的数据按照 key1=val1&key2=val2 格式进行编码,keyval 都进行了 URL 转码。

在 Express 中处理这类请求,需要使用 body-parser 中间件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// jquery

let url = `http://127.0.0.1:3001/urlencoded`,
contentType = 'application/x-www-form-urlencoded',
data = { name, email };

$.ajax({
method: 'post',
url,
contentType,
data
}).done((msg) => {
console.info(msg);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
// superagent

let url = `http://127.0.0.1:3001/urlencoded`,
data = { name, email };

request.post(url)
.type('form')
.send(data)
.then(() => {
console.info('superagent success');
}).catch((error) => {
console.error(error);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// express

// express 接收参数需要 body-parse 插件支持
const bodyParser = require('body-parser');

// 解析 application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));

app.post(['/json', '/urlencoded'], (req, res, next) => {
const { name, email} = req.body;

console.log(` name: ${name} \n email: ${email}`);
res.send('success');
});

application/json

application/json 是以 JSON 形式(序列化后的 JSON 字符串)将数据发送至服务器。

相比于 application/x-www-form-urlencodedapplication/json 支持更复杂的结构化数据,更具可读性,同时在节省带宽方面也更具优势。

在 Express 中处理这类请求,也需要使用 body-parser 中间件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// jquery

let url = `http://127.0.0.1:3001/json`,
contentType = 'application/json',
data = JSON.stringify({ name, email });

$.ajax({
method: 'post',
url,
contentType,
data
}).done((msg) => {
console.info(msg);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
// superagent

let url = `http://127.0.0.1:3001/urlencoded`,
data = JSON.stringify({ name, email });

request.post(url)
.set('content-type', contentType)
.send(data)
.then(() => {
console.info('superagent success');
}).catch((error) => {
console.error(error);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// express

// express 接收参数需要 body-parse 插件支持
const bodyParser = require('body-parser');

// 解析 application/json
app.use(bodyParser.json());

app.post(['/json', '/urlencoded'], (req, res, next) => {
const { name, email} = req.body;

console.log(` name: ${name} \n email: ${email}`);
res.send('success');
});

multipart/form-data

multipart/form-data 通过 boundary 将需要提交的数据进行分割,分割成多个 chunk 发送给服务端。

使用 JQuery Ajax 提交请求时,需要设置 processData: false

使用 Superagent 提交请求时,不能设置 content-type

在 Express 中处理这类请求,需要使用 multer 中间件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// jquery

let url = `http://127.0.0.1:3001/formData`,
contentType = 'multipart/form-data',
data = new FormData();

data.append('name', name);
data.append('email', email);

$.ajax({
method: 'post',
processData: false
url,
contentType,
data
}).done((msg) => {
console.info(msg);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// superagent

let url = `http://127.0.0.1:3001/formData`,
contentType = 'multipart/form-data',
data = new FormData();

data.append('name', name);
data.append('email', email);

request.post(url)
// .set('content-type', contentType)
.send(data)
.then(() => {
console.info('superagent success');
}).catch((error) => {
console.error(error);
});
1
2
3
4
5
6
7
8
9
10
11
12
// express

// express 接收参数需要 multer 插件支持
const bodyParser = require('multer'),
upload = multer();

app.post('/formData', upload.array(), (req, res, next) => {
const { name, email} = req.body;

console.log(` name: ${name} \n email: ${email}`);
res.send('success');
});

其他

如果使用 JQuery Ajax 时未设置 processData: false, 或使用 Superagent 设置了 content-type,服务端接收数据时会报异常:Multipart: Boundary not found