Собственный доступ к данным JSON POST с сервера Node.js.

Рассмотрим следующее HTTP POST вызов сервера Node.js:

curl -H "Content-Type: application/json" \
     -X POST \
     -d '{"jsonKey":"jsonValue"}' \
     'http://localhost:8080?abcd=efgh'

Я хотел бы получить доступ как к параметрам URL, так и к полезной нагрузке JSON запроса POST.

Доступ к параметрам URL довольно прост, если импортировать url.parse:

var server = http.createServer(function(req, res) {
        // Parse the params - prints "{ abcd: 'efgh' }"
        var URLParams = url.parse(req.url, true).query;
        console.log(URLParams);

        // How do I access the JSON payload as an object?
}

Но как мне получить доступ к полезной нагрузке JSON, используя встроенную библиотеку Node.js (без каких-либо npm Импортировать)?

Что я пробовал

  • напечатанный req в console.log, но не нашел объект POST
  • Прочитайте документацию req, который имеет тип http.IncomingMessage

2 ответа

Из документации:

При получении запроса POST или PUT тело запроса может иметь важное значение для вашего приложения. Получение данных тела немного сложнее, чем доступ к заголовкам запросов. Объект запроса, который передается обработчику, реализует интерфейс ReadableStream. Этот поток можно прослушивать или передавать в другом месте, как и любой другой поток. Мы можем получить данные прямо из потока, прослушивая события "data" и "end" потока.

https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/

var server = http.createServer(function(req, res) {
        // Parse the params - prints "{ abcd: 'efgh' }"
        var URLParams = url.parse(req.url, true).query;
        console.log(URLParams);

        // How do I access the JSON payload as an object?
        var body = [];
        req.on('data', function(chunk) {
            body.push(chunk);
        }).on('end', function() {
            body = Buffer.concat(body).toString();
            if (body) console.log(JSON.parse(body));
            res.end('It Works!!');
        });
});

req это поток, так как доступ к нему зависит от того, как вы хотите его использовать. Если вы просто хотите получить его как текст и проанализировать его как JSON, вы можете сделать следующее:

let data = "";
req.on("readable", text => data += text);
req.on("end", () => {
  try {
    const json = JSON.parse(data);
  }
  catch (err) {
    console.error("request body was not JSON");
  }
  /* now you can do something with JSON */
}); 

Просто как дополнение; Если вы хотите создать объект из тела POST, я использую следующий фрагмент кода:

const body2Obj = chunk => {
  let body = {};
  let string = chunk.toString();
  if (!string.trim()) return body;
  string.split('&').forEach(param => {
    let elements = param.split('=');
    body[elements[0]] = elements[1];
  });
  return body;
};

И затем используйте это как уже объяснено stdob-- выше:

var body = [];
req.on('data', chunk => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body);
  body = body2Obj(body);
  // ...
});

Я предпочитаю это решение вместо того, чтобы использовать негабаритный сторонний модуль для простого анализа тела запроса (иногда люди почему-то предлагают это). Возможно, у меня есть более короткая версия. Конечно, это работает только для отформатированных в URL-адресах тел.

Другие вопросы по тегам