从node.js的http.IncomingMessage获取请求正文

lor*_*o-s 9 httprequest httpserver node.js

我正在尝试为node.js编写的应用程序实现一个简单的HTTP端点.我已经创建了HTTP服务器,但现在我一直在阅读请求内容主体:

http.createServer(function(r, s) {
    console.log(r.method, r.url, r.headers);
    console.log(r.read());
    s.write("OK"); 
    s.end(); 
}).listen(42646);
Run Code Online (Sandbox Code Playgroud)

请求的方法,URL和标头打印正确,但r.read()始终为NULL.我可以说这不是请求如何产生的问题,因为content-length服务器端的头大于零.

文档说 r是一个http.IncomingMessage实现可读流接口的对象,为什么它不起作用?

lor*_*o-s 14

好的,我想我找到了解决方案.该r流(其他事物一样在node.js的,愚蠢的我...)应在异步事件驱动的方式读取:

http.createServer(function(r, s) {
    console.log(r.method, r.url, r.headers);
    var body = "";
    r.on('readable', function() {
        body += r.read();
    });
    r.on('end', function() {
        console.log(body);
        s.write("OK"); 
        s.end(); 
    });
}).listen(42646);
Run Code Online (Sandbox Code Playgroud)

  • 它不仅是一种异步方法,也是事件驱动的方法.事实上,你可以有效地使用函数,你可以将它们作为一等函数传递,你可以使用闭包(匿名函数),使这个方法成为javascript中最重要的编程方法.无论如何,我更喜欢`r.on("data",function(chunk))`你可以直接使用读数据.与"可读"相反,"数据"表示已从流中读取某些内容,而不是可读取的内容.无论如何,这是io的首选方式. (8认同)
  • @BigMan73 是对的 - 这将在正文字符串的末尾添加一个 null。看看他的回答。 (2认同)

Big*_*n73 5

“可读”事件是错误的,它错误地在主体字符串的末尾添加了一个额外的空字符

使用'data'事件处理带有块的流:

http.createServer((r, s) => {
    console.log(r.method, r.url, r.headers);
    let body = '';
    r.on('data', (chunk) => {
        body += chunk;
    });
    r.on('end', () => {
        console.log(body);
        s.write('OK'); 
        s.end(); 
    });
}).listen(42646); 
Run Code Online (Sandbox Code Playgroud)

  • 这应该是正确的答案。 (2认同)

Ble*_*ose 5

来自官方文档 https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // at this point, `body` has the entire request body stored in it as a string
});
Run Code Online (Sandbox Code Playgroud)

如果你想使用await,你可以将其转换为这样的promise:

// how to call function:
const body = await getBody(request);

// function:
function getBody(request) {
  return new Promise((resolve) => {
    const bodyParts = [];
    let body;
    request.on('data', (chunk) => {
      bodyParts.push(chunk);
    }).on('end', () => {
      body = Buffer.concat(bodyParts).toString();
      resolve(body)
    });
  });
}
Run Code Online (Sandbox Code Playgroud)