bodyParser() trong Express.js

25347

Khi lần đầu học Express, tôi đã có file app.js được viết cho tôi và tôi chỉ phải thêm một vài routes như sau để nó họat động.

app.get('/', function(req, res) {
  // get posts
  res.json(posts)
});

Nhưng sau đó, tôi đã thử setup một project Nodejs với Express từ đầu và đã cố tạo routes giống như sau

app.post('/', function(req, res) {
  Post.create(req.body)
});

nhưng nó đã không làm việc. Và errors thông báo nói về req.body không tồn tại. Tôi thực sự không hiểu lý do tại sao nó không hoạt động mặc dù tôi đã làm tất cả theo đúng trình tự.

Điều tiếp theo tôi đã làm là cố gắng kiểm tra req object. Tôi đã cố gắng để tìm thấy data trong req object. Nhưng req object quá lớn và khó hiểu và tôi không thể thực sự tìm thấy những data mà tôi đang tìm kiếm.

Cuối cùng, tôi đã tìm đến bodyParser(), và tôi đã được biết

Bạn cần phải sử dụng bodyParser() nếu bạn muốn data form có sẵn trong req.body

Nhưng tôi vẫn không thực sự hiểu tại nó hoạt động như thế nào.

app.use()

Trước tiên để sử dụng bodyParser() bạn cần sử dụng đoạn code như sau:

app.use(bodyParser.json());

Để hiểu cách thức hoạt động trên, bạn phải hiểu cách middleware hoạt động trong Express. Cụ thể, khi app.use() được sử dụng với đối số làm một function:

app.use(function(req, res) {
  // make somethings
});
  • Function sẽ đựợc thực hiện với mọi request
  • Function này sẽ hoạt động như một middleware.

Đối lập với khi app.use() được gọi với đối số là một string

app.use('/test', cb);

Nó sẽ chỉ match với request bắt đầu với /test

bodyParser.json() trả về một function và khi function đó được dùng làm đối số cho app.use, nó hoạt động giống như bất kỳ middleware khác.

var cb = bodyParser.json();
app.use(cb);

Data form trong req object

Thông tin được gửi qua internet qua các gói tin. Trong Nodejs, request object được đọc theo stream và response được ghi bởi stream.

req.on('data', function(chunk) {
  // here's the chunk
});

Mỗi lần một đoạn của dữ liệu đến, bạn có thể sử dụng nó. Ví dụ một chuỗi như sau

abcdefghijklmnopqrstuvwxyz

cũng có thể là 5 đoạn

abcde
fghij
klmno
pqrst
uvwxyz

và bạn có khả năng truy cập mỗi đoạn dữ liệu.

Như vậy dữ liệu POST sẽ không có sẵn trên đối tượng req. Nếu bạn muốn truy cập dữ liệu POST, bạn phải lấy nó từ stream

app.use(function( req, res, next ) {
  var data = '';
  req.on('data', function( chunk ) {
    data += chunk;
  });
  req.on('end', function() {
    req.rawBody = data;
    console.log( 'on end: ', data )
    if (data && data.indexOf('{') > -1 ) {
      req.body = JSON.parse(data);
    }
    next();
  });
});

bodyParser

bodyParser trả về một function hoạt động như một middleware. Chức năng lắng nghe trên req.on ('data') và xây dựng req.body từ các đoạn dữ liệu mà nó nhận được.

Nhưng có một số lưu ý. Về cơ bản, có nhiều cách khác nhau để định dạng dữ liệu bạn POST đến server:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • application/json
  • application/xml
  • maybe some others

Nói tóm lại, bodyParser phải phân tích dữ liệu một cách khác nhau tùy thuộc vào loại của nó. bodyParser hỗ trợ các function khác nhau để làm điều này.

// for parsing application/json
app.use(bodyParser.json()); 

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

// for parsing multipart/form-data
app.use(multer());

Với việc sử dụng bodyParser bạn có thể lấy được data form từ req.body

Tác giả: Bui Xuan Hien