关于Nodejs远程抓取数据有一点疑问

关于Nodejs远程抓取数据有一点疑问

http.get(“http://cnodejs.org/”, function(res) {
var chunks = [];
res.on(‘data’, function(chunk){
size += chunk.length;
chunks.push(chunk);
});
res.on(‘end’, function(){
var data = Buffer.concat(chunks, size);
console.log(data.toString())
});
}).on(‘error’, function(e) {
console.log("Got error: " + e.message);
});

上面是最简单一种形式,一般会在end里加个回调之类的, 当要抓取网页打不开的时候,会进入error,然后提示connect error之类的, 但是我发现,会先进入end里的function,之后才会报错,这要怎么处理合理呢 不像ajax有个succeed和error


5 回复

关于Node.js远程抓取数据时遇到的错误处理问题,确实是一个常见的困惑。在你的例子中,http.get 方法在请求失败时会触发 error 事件,但在某些情况下,end 事件可能会先于 error 事件被触发。这种行为通常发生在网络连接突然中断或服务器响应异常时。

为了更可靠地处理这种情况,可以采用一些改进的方法来确保错误能够及时被捕获并处理。以下是一个改进后的示例代码,展示了如何正确处理错误,并在数据获取完成后执行回调函数:

const http = require('http');

const options = {
  hostname: 'cnodejs.org',
  port: 80,
  path: '/',
  method: 'GET'
};

const req = http.request(options, (res) => {
  let chunks = [];
  let size = 0;

  res.on('data', (chunk) => {
    size += chunk.length;
    chunks.push(chunk);
  });

  res.on('end', () => {
    const data = Buffer.concat(chunks, size);
    console.log(data.toString());
  });
});

req.on('error', (e) => {
  console.error(`Request failed: ${e.message}`);
});

// 在请求结束或出错后关闭请求
req.on('close', () => {
  if (!req.aborted) {
    console.log('Request completed successfully.');
  }
});

req.end();

解释

  1. 使用 http.request 而不是 http.gethttp.request 提供了更多的灵活性,允许你在请求过程中进行更复杂的操作。而 http.get 是一个简化版本,适用于简单的 GET 请求。

  2. 错误处理:通过监听 error 事件,我们可以捕获到任何请求相关的错误。如果请求失败(例如连接超时、服务器不可达等),error 事件将被触发。

  3. end 事件:当响应完成时,end 事件将被触发。在这个事件处理程序中,我们将接收到的数据拼接起来,并转换为字符串输出。

  4. close 事件:这个事件在请求完成后被触发,无论请求是否成功。我们可以通过检查 req.aborted 属性来确定请求是否被中止。如果没有被中止,则表示请求成功完成。

这种方法确保了即使在 end 事件先于 error 事件触发的情况下,我们也能够正确地处理错误,并且保证在请求完成后执行必要的清理工作。


end 和 error 可以用一个回调函数。加一个参数表明是从哪个event回调的。

我现在是在end里有一个回调,当抓取网页有问题时返回数据为空判断的 这样可行么,之后会报连接错误

可行呀

在Node.js中,http.get请求的生命周期包括数据接收、结束和错误处理。根据你的描述,如果请求失败(例如连接错误),通常应该会触发'error'事件,而不是'end'事件。

但是,在某些情况下,'end'事件可能会先于'error'事件被触发。这是因为'end'事件表示响应已结束,而'error'事件表示请求过程中发生了错误。为了确保正确处理所有可能的情况,你可以将错误处理逻辑放在'error'事件处理器中,并且确保在任何情况下都能优雅地处理错误。

以下是一个改进后的代码示例:

const http = require('http');

http.get("http://cnodejs.org/", function(res) {
    let chunks = [];
    let size = 0;

    res.on('data', function(chunk) {
        size += chunk.length;
        chunks.push(chunk);
    });

    res.on('end', function() {
        try {
            const data = Buffer.concat(chunks, size);
            console.log(data.toString());
        } catch (err) {
            console.error('Error while processing response:', err);
        }
    });
}).on('error', function(e) {
    console.error("Got error: " + e.message);
});

解释

  1. 错误处理:在http.get调用后立即添加一个.on('error', ...)监听器来捕获任何网络错误。
  2. 数据处理:在'data'事件中收集数据片段并计算总大小。
  3. 响应结束:在'end'事件中处理接收到的数据,并使用try...catch块来捕获任何潜在的错误,例如内存不足或数据格式问题。
  4. 错误输出:使用console.error来输出错误信息,以便更容易地调试问题。

这样可以确保即使在出现错误时也能正确处理响应。如果'error'事件先于'end'事件被触发,错误处理器会捕获该错误;如果'end'事件先被触发,数据处理逻辑仍然能够正常运行。

回到顶部