zoukankan      html  css  js  c++  java
  • body-parser Node.js(Express) HTTP请求体解析中间件

    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)时受支持
  • 相关阅读:
    Bzoj1499: [NOI2005]瑰丽华尔兹
    Bzoj1016: [JSOI2008]最小生成树计数
    清橙A1212:剪枝
    SPOJ1825:Free tour II
    http://www.freepik.com/
    A Guide To Transclusion in AngularJS
    styling-customizing-file-inputs
    You Don't Know JS: this & Object Prototypes
    git中https和SSH的区别
    difference between match and exec
  • 原文地址:https://www.cnblogs.com/raind/p/8969995.html
Copyright © 2011-2022 走看看