Подтвердить что ты не робот

Node.js - получить необработанное тело запроса с помощью Express

Когда я использую Express, а мой код:

app.use(express.bodyParser());

Как я могу получить необработанное тело запроса?

4b9b3361

Ответ 1

Редактировать 2: В выпуске 1.15.2 модуля синтаксического анализатора представлен raw mode, который возвращает тело как a Buffer. По умолчанию он также автоматически обрабатывает дефляцию дефляции и 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, вам нужно будет изменить его здесь. Он также поддерживает подстановочные знаки, такие как */* или */application.


Примечание. Следующий ответ предназначен для версий до Express 4, где промежуточное программное обеспечение все еще связано с каркасом. Современный эквивалент - это модуль body-parser, который необходимо установить отдельно.

Свойство rawBody в Express было когда-то доступно, но было удалено с версии 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, который вы найдете в строке 57 анализатора JSON. Это будет выглядеть модифицированная версия.

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.

Ответ 2

У меня есть решение, которое отлично сочетается с bodyParser, используя обратный вызов verify в 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);

    }
}));

Я новичок в Node.js и express.js(начался вчера, буквально!), поэтому я хотел бы услышать комментарии к этому решению.

Ответ 3

БУДЬТЕ ОСТОРОЖНЫ с этими другими ответами, поскольку они не будут правильно играть с bodyParser, если вы хотите также поддерживать json, urlencoded и т.д. Чтобы заставить его работать с 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();
  });
});

Ответ 4

Это вариант ответа на гексацианид выше. Это промежуточное программное обеспечение также обрабатывает событие "данные", но не дожидается, когда данные будут потребляться, прежде чем вызывать "следующий". Таким образом, оба этих промежуточного программного обеспечения и 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

Это решение работало для меня:

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) { });, он не работает с куском тела запроса.