Nodejs POST 数据不完整

Nodejs POST 数据不完整

代码很简单: 获取 Post 数据. 用在配合 gitlab webhook 的,但发现经常有获取的数据不完整的情况出现, 抓包证实到这台机器的数据是完整的. 不知道有没有朋友遇到这种情况没…

<pre><code> var http = require(‘http’); http.createServer(function (req, res) { var postData = ‘’;

req.setEncoding('utf8');
req.addListener('data', function(postDataChunk) {
    postData += postDataChunk;
});

req.addListener(‘end’, function() { // handle(JSON.parse(postData)); console.log(postData); });

res.writeHead(200, {‘Content-Type’: ‘text/plain’}); res.end(“done\n”);

}).listen(8080, ‘0.0.0.0’); </code></pre>

node0.10.15 rh5


4 回复

Node.js POST 数据不完整

你提到的代码片段是用来处理 HTTP POST 请求并收集请求体中的数据。然而,如果数据不完整,可能是由于以下几个原因:

  1. 数据接收不完整:如果 postData 没有正确地接收到所有数据片段。
  2. 编码问题:确保数据以正确的编码方式被解析。
  3. 请求超时:如果请求耗时过长,可能会导致数据接收不完整。

以下是一个改进后的代码示例,使用了 streambuffer 来确保数据完整接收:

const http = require('http');

http.createServer((req, res) => {
    if (req.method === 'POST') {
        let body = [];
        
        req.on('data', (chunk) => {
            body.push(chunk);
        }).on('end', () => {
            body = Buffer.concat(body).toString();
            
            // 解析 JSON 数据
            try {
                const postData = JSON.parse(body);
                console.log(postData);
            } catch (error) {
                console.error('Failed to parse POST data:', error);
            }

            // 返回响应
            res.writeHead(200, {'Content-Type': 'text/plain'});
            res.end('done\n');
        });
    }
}).listen(8080, '0.0.0.0');

console.log('Server running at http://0.0.0.0:8080/');

解释

  1. req.on('data', ...):当接收到数据时,将数据片段存储在一个数组中。
  2. req.on('end', ...):当请求结束时,将所有数据片段拼接成一个完整的字符串,并尝试将其解析为 JSON 对象。
  3. Buffer.concat(body).toString():将多个数据片段拼接成一个完整的 Buffer,然后转换为字符串。
  4. try...catch:捕获解析 JSON 时可能出现的错误。

这种方法可以确保即使数据分多次到达,也能完整地接收并处理数据。希望这能解决你的问题!


原来是 end() 早了. 这样就 ok 了… <pre><code> req.addListener(‘end’, function() { // handle(JSON.parse(postData)); console.log(postData);

    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end("done\n");
});

// res.writeHead(200, {‘Content-Type’: ‘text/plain’}); // res.end(“done\n”);

}).listen(8080, ‘0.0.0.0’); </code></pre>

还是异步的问题……

你的问题可能是由于旧版本 Node.js 对大请求体处理不当导致的。在较新的 Node.js 版本中,这种问题已经得到了解决。以下是一个改进后的示例代码,使用 body-parser 中间件来更好地处理 POST 请求数据:

const express = require('express');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.json()); // 解析 JSON 数据
app.use(bodyParser.urlencoded({ extended: true })); // 解析 URL 编码的数据

app.post('/webhook', (req, res) => {
  const postData = req.body;
  console.log(postData);
  res.status(200).send('Received');
});

app.listen(8080, '0.0.0.0', () => {
  console.log('Server is running on port 8080');
});

在这个例子中,我们使用了 expressbody-parser 中间件来简化处理流程,并确保能够正确解析 POST 请求的数据。如果你仍然使用 Node.js 0.10.15 这个较旧的版本,建议升级到最新版 Node.js,以获得更好的性能和兼容性。

如果必须使用旧版本的 Node.js,则可以尝试增加 req.setTimeout 来避免请求超时问题,如下所示:

var http = require('http');
http.createServer(function (req, res) {
  var postData = '';

  req.setEncoding('utf8');
  req.setTimeout(60000); // 设置超时时间,单位为毫秒

  req.on('data', function(postDataChunk) {
    postData += postDataChunk;
  });

  req.on('end', function() {
    console.log(postData);
  });

  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end("done\n");

}).listen(8080, '0.0.0.0');

这样可以确保请求不会因为超时而被中断。希望这些建议能帮助你解决问题。

回到顶部