节点。使用Express获取原始请求体

时间:2022-12-20 16:58:47

When I use Express, and my code is:

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

app.use(express.bodyParser());

How would I get the raw request body?

如何获得原始请求主体?

5 个解决方案

#1


54  

Edit 2: Release 1.15.2 of the body parser module introduces raw mode, which returns the body as a Buffer. By default, it also automatically handles deflate and gzip decompression. Example usage:

编辑2:主体解析器模块的1.15.2版本引入了原始模式,它返回主体作为缓冲区。默认情况下,它还自动处理紧缩和gzip解压缩。使用示例:

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

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

By default, the options object has the following default options:

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

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

If you want your raw parser to parse other MIME types other than application/octet-stream, you will need to change it here. It will also support wildcard matching such as */* or */application.

如果您希望原始解析器解析除应用程序/八进制流之外的其他MIME类型,您需要在这里更改它。它还将支持通配符匹配,如*/*或*/应用程序。


Note: The following answer is for versions before Express 4, where middleware was still bundled with the framework. The modern equivalent is the body-parser module, which must be installed separately.

注意:下面的答案适用于Express 4之前的版本,其中中间件仍然与框架绑定。现代版的解析器模块必须单独安装。

The rawBody property in Express was once available, but removed since version 1.5.1. To get the raw request body, you have to put in some middleware before using the bodyParser. You can also read a GitHub discussion about it here.

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());

That middleware will read from the actual data stream, and store it in the rawBody property of the request. You can then access the raw body like this:

该中间件将从实际数据流中读取数据,并将其存储在请求的rawBody属性中。然后你可以像这样进入原始身体:

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

Edit: It seems that this method and bodyParser refuse to coexist, because one will consume the request stream before the other, leading to whichever one is second to never fire end, thus never calling next(), and hanging your application.

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

The simplest solution would most likely be to modify the source of bodyParser, which you would find on line 57 of Connect's JSON parser. This is what the modified version would look like.

最简单的解决方案很可能是修改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];
  ...
});

You would find the file at this location:

你可在此找到档案:

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

/ node_modules /快递/ node_modules / / lib /中间件/ json.js连接。

#2


30  

I got a solution that plays nice with bodyParser, using the verify callback in bodyParser. In this code, I am using it to get a sha1 of the content and also getting the raw body.

我得到了一个使用bodyParser的解决方案,使用bodyParser的验证回调。在这段代码中,我使用它来获取内容的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);

    }
}));

I am new in Node.js and express.js (started yesterday, literally!) so I'd like to hear comments on this solution.

我是Node的新成员。js和表达。js(从昨天开始)所以我想听听关于这个解决方案的评论。

#3


18  

BE CAREFUL with those other answers as they will not play properly with bodyParser if you're looking to also support json, urlencoded, etc. To get it to work with bodyParser you should condition your handler to only register on the Content-Type header(s) you care about, just like bodyParser itself does.

如果您还希望支持json、urlencodes等,那么请注意这些其他的答案,因为它们不能正确地与bodyParser配合。要让它与bodyParser合作,您应该让处理程序只注册您关心的内容类型头(s),就像bodyParser本身所做的那样。

To get the raw body content of a request with Content-Type: "text/plain" into req.rawBody you can do:

要将内容类型为“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();
  });
});

#4


12  

This is a variation on hexacyanide's answer above. This middleware also handles the 'data' event but does not wait for the data to be consumed before calling 'next'. This way both this middleware and bodyParser may coexist, consuming the stream in parallel.

这是hexacyanide回答的一个变化。此中间件还处理“数据”事件,但不会在调用“next”之前等待数据被消费。这样,中间件和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());

#5


11  

This solution worked for me:

这个解决方案对我起了作用:

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: '*/*' }));

When I use solution with req.on('data', function(chunk) { }); it not working on chunked request body.

当我用req的时候。(“数据”,函数(块){ });它不能处理分块请求体。

#1


54  

Edit 2: Release 1.15.2 of the body parser module introduces raw mode, which returns the body as a Buffer. By default, it also automatically handles deflate and gzip decompression. Example usage:

编辑2:主体解析器模块的1.15.2版本引入了原始模式,它返回主体作为缓冲区。默认情况下,它还自动处理紧缩和gzip解压缩。使用示例:

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

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

By default, the options object has the following default options:

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

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

If you want your raw parser to parse other MIME types other than application/octet-stream, you will need to change it here. It will also support wildcard matching such as */* or */application.

如果您希望原始解析器解析除应用程序/八进制流之外的其他MIME类型,您需要在这里更改它。它还将支持通配符匹配,如*/*或*/应用程序。


Note: The following answer is for versions before Express 4, where middleware was still bundled with the framework. The modern equivalent is the body-parser module, which must be installed separately.

注意:下面的答案适用于Express 4之前的版本,其中中间件仍然与框架绑定。现代版的解析器模块必须单独安装。

The rawBody property in Express was once available, but removed since version 1.5.1. To get the raw request body, you have to put in some middleware before using the bodyParser. You can also read a GitHub discussion about it here.

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());

That middleware will read from the actual data stream, and store it in the rawBody property of the request. You can then access the raw body like this:

该中间件将从实际数据流中读取数据,并将其存储在请求的rawBody属性中。然后你可以像这样进入原始身体:

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

Edit: It seems that this method and bodyParser refuse to coexist, because one will consume the request stream before the other, leading to whichever one is second to never fire end, thus never calling next(), and hanging your application.

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

The simplest solution would most likely be to modify the source of bodyParser, which you would find on line 57 of Connect's JSON parser. This is what the modified version would look like.

最简单的解决方案很可能是修改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];
  ...
});

You would find the file at this location:

你可在此找到档案:

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

/ node_modules /快递/ node_modules / / lib /中间件/ json.js连接。

#2


30  

I got a solution that plays nice with bodyParser, using the verify callback in bodyParser. In this code, I am using it to get a sha1 of the content and also getting the raw body.

我得到了一个使用bodyParser的解决方案,使用bodyParser的验证回调。在这段代码中,我使用它来获取内容的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);

    }
}));

I am new in Node.js and express.js (started yesterday, literally!) so I'd like to hear comments on this solution.

我是Node的新成员。js和表达。js(从昨天开始)所以我想听听关于这个解决方案的评论。

#3


18  

BE CAREFUL with those other answers as they will not play properly with bodyParser if you're looking to also support json, urlencoded, etc. To get it to work with bodyParser you should condition your handler to only register on the Content-Type header(s) you care about, just like bodyParser itself does.

如果您还希望支持json、urlencodes等,那么请注意这些其他的答案,因为它们不能正确地与bodyParser配合。要让它与bodyParser合作,您应该让处理程序只注册您关心的内容类型头(s),就像bodyParser本身所做的那样。

To get the raw body content of a request with Content-Type: "text/plain" into req.rawBody you can do:

要将内容类型为“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();
  });
});

#4


12  

This is a variation on hexacyanide's answer above. This middleware also handles the 'data' event but does not wait for the data to be consumed before calling 'next'. This way both this middleware and bodyParser may coexist, consuming the stream in parallel.

这是hexacyanide回答的一个变化。此中间件还处理“数据”事件,但不会在调用“next”之前等待数据被消费。这样,中间件和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());

#5


11  

This solution worked for me:

这个解决方案对我起了作用:

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: '*/*' }));

When I use solution with req.on('data', function(chunk) { }); it not working on chunked request body.

当我用req的时候。(“数据”,函数(块){ });它不能处理分块请求体。