Nodejs 发送HTTP消息时报错,非常诡异,求解!
Nodejs 发送HTTP消息时报错,非常诡异,求解!
正常往sina发送HTTP请求,但是会不时报如下错误, POST: api.weibo.com:443 /2/statuses/repost.json access_token=2.00rhElVDGI631Ee549f6f303v86EQB&id=3534310755900989&status=imax_check
Error: socket hang up at SecurePair.error (tls.js:948:15) at EncryptedStream.CryptoStream._done (tls.js:432:17) at EncryptedStream.CryptoStream._pull (tls.js:577:12) at SecurePair.cycle (tls.js:866:20) at EncryptedStream.CryptoStream.end (tls.js:405:13) at Socket.onend (stream.js:66:10) at Socket.EventEmitter.emit (events.js:123:20) at TCP.onread (net.js:417:51) 有人知道啥原因不?
Nodejs 发送HTTP消息时报错,非常诡异,求解!
问题描述
在使用Node.js向新浪API(api.weibo.com:443
)发送HTTP POST请求时,偶尔会遇到socket hang up
的错误。错误信息如下:
Error: socket hang up
at SecurePair.error (tls.js:948:15)
at EncryptedStream.CryptoStream._done (tls.js:432:17)
at EncryptedStream.CryptoStream._pull (tls.js:577:12)
at SecurePair.cycle (tls.js:866:20)
at EncryptedStream.CryptoStream.end (tls.js:405:13)
at Socket.onend (stream.js:66:10)
at Socket.EventEmitter.emit (events.js:123:20)
at TCP.onread (net.js:417:51)
原因分析
socket hang up
错误通常表示TCP连接被另一端关闭了。这种情况可能由多种原因引起,例如网络不稳定、服务器响应超时、或者客户端与服务器之间的连接问题。
解决方案
1. 使用 request
库
request
是一个非常流行的HTTP客户端库,可以简化HTTP请求的发送,并且提供了一些处理连接问题的方法。
首先,你需要安装 request
库:
npm install request
然后,你可以使用以下代码来发送HTTP POST请求:
const request = require('request');
const options = {
url: 'https://api.weibo.com/2/statuses/repost.json',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
access_token: '2.00rhElVDGI631Ee549f6f303v86EQB',
id: '3534310755900989',
status: 'imax_check'
}
};
request(options, (error, response, body) => {
if (error) {
console.error('Error:', error);
} else {
console.log('Response:', body);
}
});
2. 设置重试机制
为了应对偶尔的网络问题,可以在发送请求时添加重试机制。可以使用 retry
库来实现这一点:
npm install retry
然后,你可以这样修改代码:
const request = require('request');
const retry = require('retry');
const operation = retry.operation({
retries: 3,
factor: 3,
minTimeout: 1 * 1000,
maxTimeout: 60 * 1000,
randomize: true
});
operation.attempt(() => {
const options = {
url: 'https://api.weibo.com/2/statuses/repost.json',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
access_token: '2.00rhElVDGI631Ee549f6f303v86EQB',
id: '3534310755900989',
status: 'imax_check'
}
};
request(options, (error, response, body) => {
if (error) {
if (operation.retry(error)) {
return;
}
console.error('Error:', error);
} else {
console.log('Response:', body);
}
});
});
通过上述方法,你可以更好地处理网络不稳定导致的socket hang up
错误,并提高请求的成功率。
不贴代码的话我想你只应该到新浪 API 的论坛问…
data = ‘access_token=2.00rhElVDGI631Ee549f6f303v86EQB&id=3534310755900989&status=imax_check’ var options = { hostname: ‘api.weibo.com’, port: 443, path: ‘/2/statuses/repost.json’, method: ‘POST’ };
var req = http.request(options, function(res) { console.log('STATUS: ’ + res.statusCode); }); });
req.on(‘error’, function(e) { console.log('problem with request: ’ + e.message); });
// write data to request body req.write(‘data\n’); req.end();
除了一层括号有错外(我手动去掉了)… 我运行是成功的, 这不是你出错的代码对吧
var http = require('http');
var options = {
hostname: ‘api.weibo.com’,
port: 443,
path: ‘/2/statuses/repost.json’,
method: ‘POST’
};
var req = http.request(options, function(res) {
console.log('STATUS: ’ + res.statusCode);
});
req.on(‘error’, function(e) {
console.log('problem with request: ’ + e.message);
});
// write data to request body
req.write(‘data\n’);
req.end();
出错的代码和这个一模一样,我这边只有一个环境会不时的抱着个错,我看过源码包,貌似是ssl什么地方出错了,手动运行怎么都不能重现,但是就会时不时的发生这种错。。。十分无奈。
或许是新浪服务器端的不作为吧。
我的运行结果: $ node test.js STATUS: 411
443不该是用https模块来进行访问吗?
我的关于443的回复怎莫不见了?
Jackson 对 443 的建议是对的。可是我改用 https 得到相同的结果。
$ node test.js
STATUS: 411
411错误码是你post时http头content-length不对,你代码里没有发这个header,基本上4xx错误码都是客户端请求错误引起的
根据你的描述,错误信息 Error: socket hang up
通常表示网络连接问题或服务器响应超时。这种情况可能由于多种原因引起,例如网络不稳定、服务器临时不可用、请求超时等。
为了更好地调试这个问题,可以尝试以下步骤:
- 增加超时时间:有时候默认的超时时间过短可能会导致连接被提前关闭。
- 检查网络连接:确保客户端到目标服务器的网络连接是稳定的。
- 使用代理:如果目标服务器访问受限,可以尝试通过代理服务器进行访问。
- 重试机制:实现一个简单的重试机制,以便在网络不稳定时自动重试请求。
以下是一个使用 axios
库的示例代码,包含了设置超时时间和重试机制:
const axios = require('axios');
const delay = require('delay'); // npm install delay
async function sendRequest() {
const url = 'https://api.weibo.com/2/statuses/repost.json';
const options = {
method: 'POST',
url,
data: {
access_token: '2.00rhElVDGI631Ee549f6f303v86EQB',
id: '3534310755900989',
status: 'imax_check'
},
timeout: 10000, // 设置超时时间为10秒
maxRedirects: 5 // 设置最大重定向次数
};
for (let attempt = 1; attempt <= 3; attempt++) { // 尝试三次
try {
const response = await axios(options);
console.log('Response:', response.data);
return response;
} catch (error) {
console.error(`Attempt ${attempt} failed:`, error.message);
if (attempt < 3) {
await delay(1000 * attempt); // 每次重试之间延迟一秒
}
}
}
throw new Error('Failed to send request after multiple attempts');
}
sendRequest().catch(error => {
console.error('Final error:', error.message);
});
以上代码中:
- 使用了
axios
库来发送 HTTP 请求。 - 设置了超时时间为 10 秒。
- 实现了一个简单的重试机制,最多尝试三次。
- 如果三次都失败,则抛出错误。
请确保你已经安装了 axios
和 delay
这两个库:
npm install axios delay
希望这能帮助你解决问题。如果问题仍然存在,建议检查目标服务器的状态或进一步调试网络连接。