Nodejs请求超时问题? 读取一个HTTP URL的时候,假如请求的时间20秒才出来,我想要5秒就直接abort,怎么解决呀?

Nodejs请求超时问题? 读取一个HTTP URL的时候,假如请求的时间20秒才出来,我想要5秒就直接abort,怎么解决呀?

NODEJS 读取一个HTTP URL的时候,假如请求的时间20秒才出来,我想要5秒就直接abort,怎么解决呀?我使用req.setTimeout(5000,function(){req.abort();});出现了阻塞的情况。 不知道哪位知道如何解决。

5 回复

要解决Node.js中HTTP请求超时问题,并在请求超过指定时间(例如5秒)后终止请求,可以使用httphttps模块来实现。以下是一个具体的解决方案,包括代码示例和简要说明。

解决方案

  1. 使用req.setTimeout()设置超时时间:这会为请求设置一个超时时间,如果在这个时间内没有收到响应,则会触发回调函数。
  2. 监听'timeout'事件:当请求达到超时时间时,此事件会被触发。
  3. 监听'error'事件:用于处理可能出现的错误。

示例代码

const http = require('http');

function makeRequest(url) {
    return new Promise((resolve, reject) => {
        const options = {
            hostname: new URL(url).hostname,
            port: 80,
            path: new URL(url).pathname,
            method: 'GET'
        };

        const req = http.request(options, (res) => {
            let data = '';
            res.on('data', (chunk) => {
                data += chunk;
            });
            res.on('end', () => {
                resolve(data);
            });
        });

        // 设置超时时间为5秒
        req.setTimeout(5000, () => {
            console.log('请求超时');
            req.destroy();
            reject(new Error('请求超时'));
        });

        // 监听timeout事件
        req.on('timeout', () => {
            console.log('请求超时');
            req.destroy();
            reject(new Error('请求超时'));
        });

        // 监听错误事件
        req.on('error', (err) => {
            console.error('请求出错:', err.message);
            reject(err);
        });

        // 发送请求
        req.end();
    });
}

// 使用示例
makeRequest('http://example.com')
    .then(response => {
        console.log('响应数据:', response);
    })
    .catch(error => {
        console.error('发生错误:', error.message);
    });

代码解释

  • http.request() 创建一个HTTP GET请求。
  • req.setTimeout(5000) 设置请求超时时间为5秒。
  • req.on('timeout')req.setTimeout() 都会在超时后触发,调用 req.destroy() 终止请求并拒绝Promise。
  • req.on('error') 用于捕获任何可能发生的错误。
  • req.end() 发送请求。

通过这种方式,你可以有效地控制请求的超时时间,并在超过指定时间后终止请求。


没有人帮忙吗?

1分钟之后,返回一个uuid给浏览器,浏览器接收到这条指令后,再等5秒钟,再发出一条AJAX请求 ,这时,服务器看看自己运行完毕了没有,如果运行完毕了,就返回真实的数据给浏览器,否则, 又返回uuid给浏览器,浏览器继续等待…

这个不是我要的结果。我的意思是不需要客户端处理,服务器端可以直接处理的

对于这个问题,你可以使用http模块的request.setTimeout方法来设置超时时间,并且配合request.on('timeout')事件来处理超时情况。但是,如果你发现设置了超时时间后请求仍然阻塞,可以尝试使用AbortController结合fetch API来实现更灵活的请求超时控制。

使用 fetchAbortController

fetch API 提供了更好的错误处理机制,并且通过AbortController可以方便地取消请求。下面是一个使用 fetchAbortController 实现超时控制的例子:

const fetch = require('node-fetch');
const { AbortController } = require('node-abort-controller'); // 如果使用的是 Node.js 16+ 版本,可以直接用 global.AbortController

async function fetchWithTimeout(url, timeout) {
    const controller = new AbortController();
    const signal = controller.signal;

    setTimeout(() => {
        controller.abort(); // 超时后触发 abort
    }, timeout);

    try {
        const response = await fetch(url, { signal });
        if (response.ok) {
            return response.text();
        }
        throw new Error(`HTTP error! status: ${response.status}`);
    } catch (error) {
        if (error.name === 'AbortError') {
            console.log(`请求已中止,超时时间为 ${timeout}ms`);
            return null;
        } else {
            console.error('请求失败:', error);
            return null;
        }
    }
}

// 使用示例
fetchWithTimeout('http://example.com', 5000)
    .then(data => {
        if (data !== null) {
            console.log(data);
        }
    })
    .catch(error => {
        console.error('处理错误:', error);
    });

在这个例子中,我们创建了一个AbortController实例并设置了超时时间,在超时时间内如果请求没有完成,则会自动调用controller.abort()方法来中止请求。这样可以确保请求不会长时间阻塞。

注意,你需要安装node-abort-controller库来支持AbortController(如果你使用的是 Node.js 16 或更高版本,则可以直接使用内置的AbortController)。

回到顶部