Expressjs сырое тело
Как я могу получить доступ к сырому телу объекта запроса, переданного мне expressjs?
var express = require('./node_modules/express');
var app = express.createServer();
app.post('/', function(req, res)
{
console.log(req.body); //says 'undefined'
});
app.listen(80);
12 ответов
По умолчанию express
не буферизует данные, пока вы не добавите промежуточное программное обеспечение для этого. Простое решение состоит в том, чтобы следовать примеру в ответе @Stewe ниже, который просто объединит все данные самостоятельно. например
var concat = require('concat-stream');
app.use(function(req, res, next){
req.pipe(concat(function(data){
req.body = data;
next();
}));
});
Недостатком этого является то, что вы теперь переместили все содержимое тела POST в оперативную память как непрерывный блок, который может не потребоваться. Другой вариант, который стоит рассмотреть, но зависит от того, сколько данных вам нужно обработать в теле сообщения, - вместо этого обрабатывать данные в виде потока.
Например, с XML вы можете использовать синтаксический анализатор XML, который поддерживает синтаксический анализ XML, так как он поступает в виде кусков. Одним из таких парсеров будет XML Stream. Вы делаете что-то вроде этого:
var XmlStream = require('xml-stream');
app.post('/', function(req, res) {
req.setEncoding('utf8');
var xml = new XmlStream(req);
xml.on('updateElement: sometag', function(element) {
// DO some processing on the tag
});
xml.on('end', function() {
res.end();
});
});
Примерно так должно работать:
var express = require('./node_modules/express');
var app = express.createServer();
app.use (function(req, res, next) {
var data='';
req.setEncoding('utf8');
req.on('data', function(chunk) {
data += chunk;
});
req.on('end', function() {
req.body = data;
next();
});
});
app.post('/', function(req, res)
{
console.log(req.body);
});
app.listen(80);
С использованием bodyParser.text()
промежуточное ПО поместит текстовое тело в req.body
,
app.use(bodyParser.text({type: '*/*'}));
Если вы хотите ограничить обработку текстового тела определенными маршрутами или размещать типы контента, вы можете сделать это тоже.
app.use('/routes/to/save/text/body/*', bodyParser.text({type: 'text/plain'})); //this type is actually the default
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
Если вы хотите сырье Buffer
, ты можешь использовать bodyParse.raw()
,
app.use(bodyParser.raw({type: '*/*'}));
Примечание: этот ответ был проверен на узле v0.12.7, экспресс 4.13.2 и body-parser 1.13.3.
Поместите следующее промежуточное ПО перед промежуточным программным обеспечением bodyParser. Он будет собирать необработанные данные тела в request.rawBody и не будет мешать bodyParser.
app.use(function(req, res, next) {
var data = '';
req.setEncoding('utf8');
req.on('data', function(chunk) {
data += chunk;
});
req.on('end', function() {
req.rawBody = data;
next();
});
});
app.use(express.bodyParser());
app.use(bodyParser.json({
verify: function (req, res, buf, encoding) {
req.rawBody = buf;
}
}));
app.use(bodyParser.urlencoded({
extended: false,
verify: function (req, res, buf, encoding) {
req.rawBody = buf;
}
}));
Таким образом, похоже, что bodyParser Express анализирует только входящие данные, если content-type
устанавливается на одно из следующих:
application/x-www-form-urlencoded
application/json
multipart/form-data
Во всех других случаях это даже не беспокоит чтение данных.
Вы можете изменить строку №. 92 из экспресс /node_modules/connect/lib/middleware/bodyParser.js из
} else {
next();
}
Для того, чтобы:
} else {
var data='';
req.setEncoding('utf8');
req.on('data', function(chunk) {
data += chunk;
});
req.on('end', function() {
req.rawBody = data;
next();
});
}
А потом прочитайте req.rawBody
из вашего кода.
Все ответы кажутся устаревшими, если кто-то все еще борется с этим, то экспресс имеет встроенное промежуточное ПО Express .
Это промежуточное ПО доступно в версии Express v4.16.0 и выше. Это встроенная промежуточная функция в Express. Он анализирует входящие запросы с полезными данными JSON и основан на анализаторе тела.
var express = require("express");
var app = express();
app.use(express.raw({ type: "*/*" }))
app.post("/", (req, res) => {
// req.body = JSON.parse(req.body); // To parse JSON if needed (in-case)
console.log(req.body);
res.end();
});
app.listen(3000, (err) => {
if(!err) console.log("App running!!")
});
Если вы хотите тело в качестве буфера:
var rawParser = function(req, res, next) {
var chunks = [];
req.on('data', function(chunk) {
chunks.push(chunk)
});
req.on('end', function() {
req.body = Buffer.concat(chunks);
next();
});
}
или же
var rawParser = bodyParser.raw({type: '*/*'});
а потом:
app.put('/:name', rawParser, function(req, res) {
console.log('isBuffer:', Buffer.isBuffer(req.body));
})
или для всех маршрутов:
app.use(bodyParser.raw({type: '*/*'}));
Кажется, теперь стало намного проще!
Модуль body-parser теперь может анализировать необработанные и текстовые данные, что делает задачу одной строкой:
app.use(bodyParser.text({type: 'text/plain'}))
ИЛИ ЖЕ
app.use(bodyParser.raw({type: 'application/binary'}))
Обе строки просто заполняют body
свойство, поэтому получите текст с res.body
,bodyParser.text()
даст вам строку UTF8 в то время как bodyParser.raw()
дам тебе
Это полный код для текстовых / простых данных:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
app.use(bodyParser.text({type: 'text/plain'}))
app.post('/', function (req, res, next) {
console.log('body:\n' + req.body)
res.json({msg: 'success!'})
next()
})
Смотрите здесь для полной документации: https://www.npmjs.com/package/body-parser
Я использовал Express 4.16 и Body-Parser 1.18
Если у вас возникли проблемы с вышеуказанными решениями, мешающими обычным почтовым запросам, может помочь что-то вроде этого:
app.use (function(req, res, next) {
req.rawBody = '';
req.setEncoding('utf8');
req.on('data', function(chunk) { req.rawBody += chunk });
});
Дополнительная информация и источник: https://github.com/visionmedia/express/issues/897
БУДЬТЕ ОСТОРОЖНЫ с этими другими ответами, так как они не будут правильно работать с bodyParser, если вы хотите также поддерживать json, urlencoded и т. Д. Чтобы заставить его работать с bodyParser, вы должны обработать ваш обработчик только для регистрации на Content-Type
Заголовки, которые вас интересуют, как и сам bodyParser.
Чтобы получить необработанное содержание тела запроса с Content-Type: "text/xml"
в req.rawBody
ты можешь сделать:
app.use(function(req, res, next) {
var contentType = req.headers['content-type'] || ''
, mime = contentType.split(';')[0];
if (mime != 'text/xml') {
return next();
}
var data = '';
req.setEncoding('utf8');
req.on('data', function(chunk) {
data += chunk;
});
req.on('end', function() {
req.rawBody = data;
next();
});
});
При отправке запроса обязательно добавьте этот заголовок:
'Content-Type': 'application/json'