当我使用Express时,我的代码如下:
app.use(express.bodyParser());
我该如何获取原始请求正文?
编辑2: body parser 模块的1.15.2版本引入原始模式,它返回请求体作为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'
};
如果您想让您的原始解析器解析除了application/octet-stream
以外的其他MIME类型,则需要在此处进行更改。它还将支持通配符匹配,例如*/*
或*/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
。
我有一个解决方案,可以与 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都很新(从昨天开始,真的!),所以我想听听对这个解决方案的评论。
req.rawBody = buf.toString();
并从verify
函数中去掉了其余的部分,因为那就是我所需要的全部内容,它很好地发挥了作用。不需要更改bodyParser
源代码! - Gregreq.rawBody = buf.toString(encoding);
。 - shaharsolapplication/json
请求。 - Pavel Evstigneev这个解决方案对我有效:
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) { });
的解决方案时,它无法处理分块请求主体。
小心那些其他答案,如果你想支持json、urlencode等格式,它们可能无法与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();
});
});
app.use(bodyParser.urlencoded({limit: '80mb', extended: true})); app.use(bodyParser.json({limit: '80mb'})); app.use(bodyParser.raw({type: 'application/octet-stream'}))
这段代码是用于在应用程序中使用body-parser中间件,它可以解析HTTP请求的主体,并将其转换为JavaScript对象。其中,urlencoded方法用于解析表单数据,json方法用于解析JSON格式的数据,raw方法用于解析二进制数据。此外,通过设置limit属性,可以限制请求主体的大小。 - Soumya Kanti这是对hexacyanide上面答案的一种变化。这个中间件也处理“data”事件,但在调用“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());
req.on('end', ... )
中。如果您想要完整的请求,您需要等待直到那时。 - Chris Cinelli// 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;
我已经解决了向头部属性添加的问题。
{"Content-Type": "application/json"}
使用
app.use(express.json());
或者
app.use(express.text());
或者
app.use(express.urlencoded());
app.use(bodyParser.text());
app.use(bodyParser.urlencoded());
app.use(bodyParser.raw());
app.use(bodyParser.json());
例如,如果您应该获取原始文本文件,请运行.text()
。
这是目前body-parser支持的。
express.raw
在使用 Google Cloud Tasks 时无法正常工作,因为 Tasks 没有在 http 任务中发送content-type
头。我能够手动指定头并从那里使其工作。返回了一个缓冲区,我使用一些自定义中间件将其转换为 JSON。 - knownasilya