express从4.0之后,就将body-parser分离出来,需要通过npm独立安装,之前在自己的项目中没有发现任何的问题,今天突然出现了一个问题,排查了好长时间才得以解决,拿出来和大家分享一下并且也顺便学习一下body-parser。 我的代码如下: app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var user = require('./routes/user');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/user', user);
user.js
var express = require('express');
var path = require('path');
var userController = require('../controller/userController');
var router = express.Router();
router.post('/register', function (req, res, next) {
const username = req.body.username;
const password = req.body.password;
console.log(JSON.stringify(req.body));
});
ajax请求:
var username = $('#username').val();
var password = $('#password').val();
if(username && password){
//提交表单
$.ajax({
url: '/user/register ',
type: 'post',
dataType: 'json',
data: JSON.stringify({
username: username,
password: password
}),
success: function (data) {
if(data && data.status && data.status == 'success'){
window.location= '/user/login';
}
else {
alert('注册出错啦');
}
}
});
}
之后出现了一个很奇怪的现象,username
和password
都是undefinded
,而
console.log(JSON.stringify(req.body));
//{"{\"username\":\"test\",\"password\":\"test\"}":""}
发现自己犯了一个错误,我在ajax
请求中的data中使用了JSON.stringify()
,将JSON
转化成了String
类型,导致后来的解析是无效的。
后来学习了一下body-parser,其中有四个函数
- json()
- raw()
- text()
- urlencoded()
分别是处理json数据、Buffer流数据、文本数据、UTF-8的编码的数据。所以在我app配置了1和2的情况下是无法正确解析的。 看到一个对body-parser不错的一段话,拿出来和大家一起分享一下。
在express项目中,通常顺序调用body-parser所提供的parser,这样当一个parser无法满足post参数解析条件时,还可以使用另一个parser进行解析(在某些特殊的请求中,有可能所有parser均无法解析)。
但body-parser的各个parser在解析的过程中,若对满足解析条件的post参数进行了解析,req作为一个stream对象,已经被消耗,无法再使用另一个parser对post参数解析,也即post参数只能被第一个满足解析条件的parser进行解析。因此即使先后调用raw、json、urlencoded这三个parser,也只能得到一个body,具体格式由各parser的调用次序及post参数满足的解析条件决定。