三種 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
格式進行編碼,key
和 val
都進行了 URL 轉碼。
在 Express 中處理這類請求,需要使用
body-parser
中介軟體。
// 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);
})
複製程式碼
// 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);
});
複製程式碼
// 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-urlencoded
,application/json
支援更復雜的結構化資料,更具可讀性,同時在節省頻寬方面也更具優勢。
在 Express 中處理這類請求,也需要使用
body-parser
中介軟體。
// 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);
})
複製程式碼
// 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);
});
複製程式碼
// 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
中介軟體。
// 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);
})
複製程式碼
// 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);
});
複製程式碼
// 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
。