node微服务中的body从何而来——bodyParser

158 阅读1分钟

bodyParser

作为express的一个中间件,bodyparser承担了接受请求的一个重要参数body的功能

源代码浏览路径

body-parser.svg

逐步解释

文件入口

文件入口在 node_modules\body-parser\index.js

// 逐步定义了 json raw text urlencoded四种属性
Object.defineProperty(exports, 'json', {
  configurable: true,
  enumerable: true,
  get: createParserGetter('json')
})
Object.defineProperty(exports, 'raw', {
  configurable: true,
  enumerable: true,
  get: createParserGetter('raw')
})

Object.defineProperty(exports, 'text', {
  configurable: true,
  enumerable: true,
  get: createParserGetter('text')
})
Object.defineProperty(exports, 'urlencoded', {
  configurable: true,
  enumerable: true,
  get: createParserGetter('urlencoded')
})
// 在以上代码中,用get属性来加载不同的parser
function createParserGetter(name) {
  return function get() {
    return loadParser(name)
  }
}
// 工厂模式来拿不同类型的parser
function loadParser(parserName) {
  var parser = parsers[parserName]

  if (parser !== undefined) {
    return parser
  }

  // this uses a switch for static require analysis
  switch (parserName) {
    case 'json':
      parser = require('./lib/types/json')
      break
    case 'raw':
      parser = require('./lib/types/raw')
      break
    case 'text':
      parser = require('./lib/types/text')
      break
    case 'urlencoded':
      parser = require('./lib/types/urlencoded')
      break
  }

  // store to prevent invoking require()
  return (parsers[parserName] = parser)
}

重点 :下面仅说明json类型

这里仅指明几处关键代码的作用

  1. node_modules\body-parser\lib\types\json.js
// 对内部变量进行赋值
var opts = options || {}
  var limit = typeof opts.limit !== 'number'
    ? bytes.parse(opts.limit || '100kb')
    : opts.limit
  var inflate = opts.inflate !== false
  var reviver = opts.reviver
  var strict = opts.strict !== false
  var type = opts.type || 'application/json'
  var verify = opts.verify || false
  
  // 指出当前请求的type 即应该格式化的类型
   var shouldParse = typeof type !== 'function'
    ? typeChecker(type)
    : type
 
 // 设置字符集
  var charset = getCharset(req) || 'utf-8'
  // 写入到内存中
   read(req, res, next, parse, debug, {
      encoding: charset,
      inflate: inflate,
      limit: limit,
      verify: verify
    })
  1. node_modules\body-parser\lib\read.js
 // 书接上文
 // 在read函数中读取数据并写入
 stream = contentstream(req, debug, opts.inflate)
 ------------
 // 根据不同的编码规则 来写入
 switch (encoding) {
  case 'deflate':
    stream = zlib.createInflate()
    debug('inflate body')
    req.pipe(stream)
    break
  case 'gzip':
    stream = zlib.createGunzip()
    debug('gunzip body')
    req.pipe(stream)
    break
  case 'identity':
    stream = req
    stream.length = length
    break
  default:
    throw createError(415, 'unsupported content encoding "' + encoding + '"', {
      encoding: encoding,
      type: 'encoding.unsupported'
    })
  }
 -------------------