body-parser Node.js(Express) HTTP请求体解析中间件

2016年06月08日     781     声明

在HTTP请求中,POSTPUTPATCH三种请求方法中包含请求体,Node.js 原生HTTP模块中,请求体要基于流的方式接收和解析。body-parser是一个HTTP请求体解析中间件,使用这个模块可以解析JSON、Raw、文本、URL-encoded格式的请求体,Express框架中就是使用这个模块做为请求体解析中间件。

  1. 请求体解析

  2. 请求体解析

1. 请求体解析

1.1 原生环境中的解析

Node.js 原生HTTP模块中,是将用户请求数据封装到了用于请求对象req中,该对象是一个IncomingMessage,该对象同时也是一个可读流对象。在原生HTTP服务器,或不依赖第三方解析模块时,可以像下面这样接收并解析请求体:

const http = require('http');

//用http模块创建一个http服务端
http.createServer(function(req, res) {
if (req.method.toLowerCase() === 'post') {
var body = '';
req.on('data', function(chunk){
body += chunk;
}); req.on('end', function(){
if(req.headers['content-type'].indexOf('application/json')!==-1){
// JSON 格式请求体解析
JSON.parse(body);
} else if(req.headers['content-type'].indexOf('application/octet-stream')!==-1){
// Raw 格式请求体解析
// ……
} else if(req.headers['content-type'].indexOf('text/plain')!==-1){
// text 文本格式请求体解析
// ……
} else if(req.headers['content-type'].indexOf('application/x-www-form-urlencoded')!==-1){
// URL-encoded 格式请求体解析
// ……
} else {
// 其它格式解析
}
})
} else {
res.end('其它提交方式');
}
}).listen(3000);

1.2 使用body-parser解析请求体

body-parser模块是一个Express/Connect中间件,它使用非常简单且功能强大,可以像下面这样用这个模块解析请求体:

Express/Connect 项层处理

Express框架默认使用body-parser做为请求体解析中间件,创建Express项目后,可以在app.js文件中看到如下代码:

/* 引入依赖项 */
var express = require('express');
// ……
var bodyParser = require('body-parser'); var routes = require('./routes/index');
var users = require('./routes/users'); var app = express(); // …… // 解析 application/json
app.use(bodyParser.json());
// 解析 application/x-www-form-urlencoded
app.use(bodyParser.urlencoded());

这样就在项目的Application级别,引入了body-parser模块处理请求体。在上述代码中,模块会处理application/x-www-form-urlencodedapplication/json两种内容格式的请求体。经过这个中间件处理后,就可以在所有路由处理器的req.body中访问请求参数。

解析Express具体路由

在实际应用中,不同路径(路由)可能会要求用户使用不同的内容类型,body-parser还支持为单个Express路由添加请求体解析:

var express = require('express')
var bodyParser = require('body-parser') var app = express() // 创建 application/json 解析
var jsonParser = bodyParser.json() // 创建 application/x-www-form-urlencoded 解析
var urlencodedParser = bodyParser.urlencoded({ extended: false }) // POST /login 获取 URL编码的请求体
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
res.send('welcome, ' + req.body.username)
}) // POST /api/users 获取 JSON 编码的请求体
app.post('/api/users', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
// create user in req.body
})

指定请求类型

body-parser还支持为某一种或一类内容类型的请求体指定解析方式,指定时可以通过在解析方法中添加type参数修改指定Content-Type的解析方式。

如,可以对text/plain内容类型使用JSON解析:

app.use(bodyParser.json({ type: 'text/plain' }))

这一选项更多是用在非标准请求头的解析中,如下:

// 解析自定义的 JSON
app.use(bodyParser.json({ type: 'application/*+json' })) // 解析自定义的 Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' })) // 将 HTML 请求体做为字符串处理
app.use(bodyParser.text({ type: 'text/html' }))

2. body-parser模块的API

通过npm install body-parser命令安装模块后,可以通过以下方式获取模块引用:

var bodyParser = require('body-parser')

bodyParser变量是对中间件的引用。请求体解析后,解析值都会被放到req.body属性,内容为空时是一个{}空对象。

2.1 bodyParser.json() - 解析JSON格式

bodyParser.json(options)

返回一个仅解析json格式数据的中间件。这个方法支持任意Unicode编码的请求体,且支持gzipdeflate编码的数据压缩。

Option是一个包含以下可选值的对象

  • inflate - 设置为true时,deflate压缩数据会被解压缩;设置为true时,deflate压缩数据会被拒绝。默认为true
  • limit - 设置请求的最大数据量。默认为'100kb'
  • reviver - 传递给JSON.parse()方法的第二个参数,详见JSON.parse()
  • strict - 设置为true时,仅会解析ArrayObject两种格式;设置为false会解析所有JSON.parse支持的格式。默认为true
  • type - 该选项用于设置为指定MIME类型的数据使用当前解析中间件。这个选项可以是一个函数或是字符串,当是字符串是会使用type-is来查找MIMI类型;当为函数是,中间件会通过fn(req)来获取实际值。默认为application/json
  • verify - 这个选项仅在verify(req, res, buf, encoding)时受支持

2.2 bodyParser.raw() - 解析二进制格式

bodyParser.raw(options)

返回一个将所有数据做为Buffer格式处理的中间件。这个方法支持gzipdeflate编码的数据压缩。解析后,其后的所有的req.body中将会是一个Buffer数据。

Option是一个包含以下可选值的对象

  • inflate - 设置为true时,deflate压缩数据会被解压缩;设置为true时,deflate压缩数据会被拒绝。默认为true
  • limit - 设置请求的最大数据量。默认为'100kb'
  • type - 该选项用于设置为指定MIME类型的数据使用当前解析中间件。这个选项可以是一个函数或是字符串,当是字符串是会使用type-is来查找MIMI类型;当为函数是,中间件会通过fn(req)来获取实际值。默认为application/octet-stream
  • verify - 这个选项仅在verify(req, res, buf, encoding)时受支持

2.3 bodyParser.text() - 解析文本格式

bodyParser.text(options)

返回一个仅处理字符串格式处理的中间件。这个方法支持gzipdeflate编码的数据压缩。解析后,其后的所有的req.body中将会是一个字符串值。

Option是一个包含以下可选值的对象

  • defaultCharset - 如果Content-Type后没有指定编码时,使用此编码。默认为'utf-8'
  • inflate - 设置为true时,deflate压缩数据会被解压缩;设置为true时,deflate压缩数据会被拒绝。默认为true
  • limit - 设置请求的最大数据量。默认为'100kb'
  • type - 该选项用于设置为指定MIME类型的数据使用当前解析中间件。这个选项可以是一个函数或是字符串,当是字符串是会使用type-is来查找MIMI类型;当为函数是,中间件会通过fn(req)来获取实际值。默认为application/octet-stream
  • verify - 这个选项仅在verify(req, res, buf, encoding)时受支持

2.4 bodyParser.urlencoded() - 解析文本格式

bodyParser.urlencoded(options)

返回一个处理urlencoded数据的中间件。这个方法默认使用UTF-8编码,且支持gzipdeflate编码的数据压缩。解析后,其后的所有的req.body中将会是一个键值对对象。

Option是一个包含以下可选值的对象

  • extended - 当设置为false时,会使用querystring库解析URL编码的数据;当设置为true时,会使用qs库解析URL编码的数据。后没有指定编码时,使用此编码。默认为true
  • inflate - 设置为true时,deflate压缩数据会被解压缩;设置为true时,deflate压缩数据会被拒绝。默认为true
  • limit - 设置请求的最大数据量。默认为'100kb'
  • parameterLimit - 用于设置URL编码值的最大数据。默认为1000
  • type - 该选项用于设置为指定MIME类型的数据使用当前解析中间件。这个选项可以是一个函数或是字符串,当是字符串是会使用type-is来查找MIMI类型;当为函数是,中间件会通过fn(req)来获取实际值。默认为application/octet-stream
  • verify - 这个选项仅在verify(req, res, buf, encoding)时受支持

body-parser Node.js(Express) HTTP请求体解析中间件的更多相关文章

  1. Node.js + Express 接口请求(GET、POST、PUT)事例

    路由 路由是指应用程序的端点(URI)如何响应客户端请求.有关路由的介绍,请参阅基本路由. 您可以使用Express app对象的方法定义路由,这些方法对应于HTTP方法; 例如,app.get()处 ...

  2. body-parser 是一个Http请求体解析中间件

    1.这个模块提供以下解析器 (1) JSON body parser (2) Raw body parser (3)Text body parser (4)URL-encoded form body ...

  3. Node.js Express框架

    Express 介绍 Express是一个最小的,灵活的Node.js Web应用程序框架,它提供了一套强大的功能来开发Web和移动应用程序. 它有助于基于Node Web应用程序的快速开发.下面是一 ...

  4. node.js+express+mongoose实现用户增删查改案例

    node.js+express+mongodb对用户进行增删查改 一.用到的相关技术 使用 Node.js 的 express 框架搭建web服务 使用 express 中间件 body-parse ...

  5. Node.js Express 框架学习

    转载:http://JavaScript.ruanyifeng.com/nodejs/express.html#toc0 感觉很牛的样子,不过觉得对初学者没太大用,里面很多例子用的api都没有详细的说 ...

  6. Node.js Express 框架

    Node.js Express 框架 Express 简介 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP ...

  7. Node.js GET/POST请求

    在很多场景中,我们的服务器都需要跟用户的浏览器打交道,如表单提交. 表单提交到服务器一般都使用GET/POST请求. 我将为大家介绍 Node.js GET/POST请求. 获取GET请求内容 由于G ...

  8. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

  9. Nodejs学习笔记(六)—Node.js + Express 构建网站预备知识

    前言 前面经过五篇Node.js的学习,基本可以开始动手构建一个网站应用了,先用这一篇了解一些构建网站的知识! 主要是些基础的东西... 如何去创建路由规则.如何去提交表单并接收表单项的值.如何去给密 ...

随机推荐

  1. Tarjan 模板,高级并查集

    第一个模板有误!!!! 请见谅!!! 要怪就怪HDU吧,竟然让我过了 第二个模板是正确的.请翻到下面看更新 HDU 1269 评论区居然有人说用并查集过了,其实回想一下 求无向图的连通分量,就是并查集 ...

  2. springboot整合freemarker

    前后端分离现在越来越多,如何有效的使用springboot来整合我们的页面是一个很重要的问题. springboot整合freemarker有以下几个步骤,也总结下我所犯的错误: 1.加依赖: 2.配 ...

  3. Python基础【day03】:入门知识拾遗(八)

    本节内容 1.作用域 2.三元运算 3.进制 一.作用域 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. 1 2 3 if 1==1:     name = 'wupeiq ...

  4. JAVA记录-java代码优化策略

    java代码优化策略 1.生成对象时,合理分配空间和大小:new ArrayList(100); 2.优化for循环: Vector vect = new Vector(1000); For(int ...

  5. golang基础数据结构链表

    链表 链表(Linked list),是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer). 每个节点包含下一个节点的地址,这样把所有的节点串起来了, ...

  6. Python复习笔记(一)高级变量类型

    目标 列表元组 字典 字符串 公共方法 变量高级 01. 列表 02. 元组 03. 字典 04. 字符串 1)判断类型 - 9 2) 查找和替换 - 7 3) 大小写转换 - 5 4) 文本对齐 - ...

  7. JavaScript数组倒序函数reverse()

    左边为原数组,右边为array.reverse()的结果: 函数很简单,但是 var temp = ChartConfig.getMonthData(); $scope.monthList = tem ...

  8. JS 互相调用iframe页面中js方法、VUE里 iframe 互调方法

    1,父 html 调用子 iframe 内方法: document.getElementById("iframe").contentWindow.func(data1,data2. ...

  9. 【原创】angularjs1.3.0源码解析之执行流程

    Angular执行流程 前言 发现最近angularjs在我厂的应用变得很广泛,下周刚好也有个angular项目要着手开始做,所以先做了下功课,从源代码开始入手会更深刻点,可能讲的没那么细,侧重点在于 ...

  10. bzoj 1724 优先队列 切割木板

    倒着的石子合并,注意不是取当前最长木板贪心做,而是取当前最小累加答案: 例如 4 5 6 7 若按第一种思路:ans=22+15+9 第二种:ans=22+13+9,可以先从中间某一块分开,这样答案更 ...