97

当我使用 Express 时,我的代码是:

app.use(express.bodyParser());

我将如何获得原始请求正文

4

9 回答 9

102

编辑 2: body parser 模块的 1.15.2 版引入了raw mode,它将 body 作为Buffer返回。默认情况下,它还会自动处理 deflate 和 gzip 解压缩。示例用法:

var bodyParser = require('body-parser');
app.use(bodyParser.raw(options));

app.get(path, function(req, res) {
  // req.body is a Buffer object
});

默认情况下,该options对象具有以下默认选项:

var options = {
  inflate: true,
  limit: '100kb',
  type: 'application/octet-stream'
};

如果您希望原始解析器解析除 之外的其他 MIME 类型application/octet-stream,则需要在此处进行更改。它还将支持通配符匹配,例如*/*or */application


注意:以下答案适用于 Express 4 之前的版本,其中中间件仍与框架捆绑在一起。现代的等价物是body-parser模块,它必须单独安装。

Express 中的rawBody属性曾经可用,但从 1.5.1 版本开始被删除。要获取原始请求正文,您必须在使用 bodyParser 之前放入一些中间件。您还可以在此处阅读有关它的 GitHub 讨论。

app.use(function(req, res, next) {
  req.rawBody = '';
  req.setEncoding('utf8');

  req.on('data', function(chunk) { 
    req.rawBody += chunk;
  });

  req.on('end', function() {
    next();
  });
});
app.use(express.bodyParser());

该中间件将从实际数据流中读取,并将其存储在rawBody请求的属性中。然后,您可以像这样访问原始正文:

app.post('/', function(req, res) {
  // do something with req.rawBody
  // use req.body for the parsed body
});

编辑:似乎此方法和 bodyParser 拒绝共存,因为一个会在另一个之前消耗请求流,导致第二个永远不会触发end,因此永远不会调用next(),并挂起您的应用程序。

最简单的解决方案很可能是修改 bodyParser 的源代码,您可以在Connect 的 JSON 解析器的第 57 行找到它。这就是修改后的版本。

var buf = '';
req.setEncoding('utf8');
req.on('data', function(chunk){ buf += chunk });
req.on('end', function() {
  req.rawBody = buf;
  var first = buf.trim()[0];
  ...
});

您将在此位置找到该文件:

/node_modules/express/node_modules/connect/lib/middleware/json.js.

于 2013-09-10T03:30:36.077 回答
49

我得到了一个与 bodyParser 配合得很好的解决方案,使用 bodyParser 中的verify回调。在这段代码中,我使用它来获取内容的 sha1 并获取原始正文。

app.use(bodyParser.json({
    verify: function(req, res, buf, encoding) {

        // sha1 content
        var hash = crypto.createHash('sha1');
        hash.update(buf);
        req.hasha = hash.digest('hex');
        console.log("hash", req.hasha);

        // get rawBody        
        req.rawBody = buf.toString();
        console.log("rawBody", req.rawBody);

    }
}));

我是 Node.js 和 express.js 的新手(从字面上看是昨天开始的!)所以我想听听对此解决方案的评论。

于 2014-10-29T15:29:11.120 回答
44

这个解决方案对我有用:

var rawBodySaver = function (req, res, buf, encoding) {
  if (buf && buf.length) {
    req.rawBody = buf.toString(encoding || 'utf8');
  }
}

app.use(bodyParser.json({ verify: rawBodySaver }));
app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
app.use(bodyParser.raw({ verify: rawBodySaver, type: '*/*' }));

当我使用解决方案时,req.on('data', function(chunk) { });它不适用于分块的请求正文。

于 2016-02-26T12:32:34.470 回答
30

请注意其他答案,因为如果您希望还支持 json、urlencoded 等,它们将无法与 bodyParser 正常播放。要使其与 bodyParser 一起使用,您应该将处理程序设置为仅在Content-Type您的标头上注册关心,就像 bodyParser 本身一样。

Content-Type: "text/plain"要获取请求的原始正文内容,req.rawBody您可以执行以下操作:

app.use(function(req, res, next) {
  var contentType = req.headers['content-type'] || ''
    , mime = contentType.split(';')[0];

  if (mime != 'text/plain') {
    return next();
  }

  var data = '';
  req.setEncoding('utf8');
  req.on('data', function(chunk) {
    data += chunk;
  });
  req.on('end', function() {
    req.rawBody = data;
    next();
  });
});
于 2014-04-04T01:10:32.950 回答
16

这是上面六氰化物答案的变体。该中间件还处理“数据”事件,但在调用“下一个”之前不会等待数据被使用。这样,这个中间件和 bodyParser 可以共存,并行使用流。

app.use(function(req, res, next) {
  req.rawBody = '';
  req.setEncoding('utf8');

  req.on('data', function(chunk) { 
    req.rawBody += chunk;
  });

  next();
});
app.use(express.bodyParser());

于 2014-01-19T20:54:57.270 回答
1
// Change the way body-parser is used
const bodyParser = require('body-parser');

var rawBodySaver = function (req, res, buf, encoding) {
  if (buf && buf.length) {
    req.rawBody = buf.toString(encoding || 'utf8');
  }
}
app.use(bodyParser.json({ verify: rawBodySaver, extended: true }));




// Now we can access raw-body any where in out application as follows
request.rawBody;
于 2021-02-16T16:28:50.150 回答
1

2022年

进入每个 API的最佳方法raw body是将缓冲区转换为字符串。

在此处输入图像描述

app.use(
  express.json({
    limit: '5mb',
    verify: (req, res, buf) => {
      req.rawBody = buf.toString();
    },
  })
);
于 2022-02-02T07:37:12.150 回答
0

利用

app.use(express.json());

或者

app.use(express.text());

或者

app.use(express.urlencoded());

取决于您的原始格式

于 2021-10-14T17:23:19.960 回答
-1

使用body-parser解析正文:

app.use(bodyParser.text());

app.use(bodyParser.urlencoded());

app.use(bodyParser.raw());

app.use(bodyParser.json());

IE。如果您应该获取原始文本文件,请运行.text().

这就是 body-parser 目前支持的

于 2019-03-27T00:19:40.707 回答