2016-09-15 20:30:26

Node.js: 让express 4.X 解析任意请求

前几日探索了一下让express解析XML的办法, 今天发现了一个可以解析任意content-type的简单方法, 在此做个记录

bodyParser.raw

阅读body-parser的官方文档via,发现bodyParser.raw可以解析任意请求头, 只需要传入一个type字符串或type函数即可了

app.use(bodyParser.raw({
  type: "text/calendar",
  verify: function(req, res, buf, encoding) {
  //  log.error("get the content type-"+req.headers["content-type"])
  //  log.error(buf.toString(encoding || "utf8"))
    if(buf && buf.length) {
      // Store the raw XML
      req.rawBody = buf.toString(encoding || "utf8");
    }
  }
}));

如上代码, 如果type为字符串, 则将其当为要解析的content-type.

更高级的用法为函数形式, 参数为原生的被express包装过的那个经典req对象:

  type: function(req){
    var contentType = req.headers["content-type"];
    var defaultParseArr = ["text/calendar"];
    var shouldParse = false;
    defaultParseArr.forEach(function(item,index){
      if(contentType.indexOf(item) != -1){
        shouldParse = true;
      }
    });
    return shouldParse; 
  },

则可以通过指定返回Boolean值来确定是否解析.

bodyParser对type的声明在这里via,

注意点

req.headers["content-type"]很可能包含多个content-type和charset等信息, 需要自己解析一下,无脑匹配很可能会出错

bodyParser中间件的执行顺序

理论上来说express一定是顺序执行的, 但是bodyParser中使用了req._body来当作flag, 如果为真, 则接下来的bodyParser的中间件会全部跳过, 具体源码在这里:

校验处

设置处

个人觉得bodyParser旗下的中间件真实的执行效果与express中间件串行执行的思想冲突非常严重, 开发者很难注意到bodyParser的真实效果, 也许这也是为什么express会将bodyParser分离出去的原因

但是,即使bodyParser被分离了,它仍然被express-generator等脚手架设为默认使用, 这与express"小而精"的哲学产生了冲突, 在这一点上, koa确实超过了express.

不过话说回来,koa官方又想用async/await,又说使用Babel的开发体验不能忍受, 产生的结果便是一直没进入stable状态的koa2,这思想真是纠结,对我个人而言,这把它从"小而精"中赚的分全给丢光了, 因此我目前一直在用express+babel

本文链接:https://smallpath.me/post/express-parser-raw

-- EOF --