Last updated
Last updated
再配合JS加密,效果更好
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Concurrent Polling</title>
</head>
<body>
<script>
// 域名列表,客户端将轮询这些域名
const domains = [
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"baidu.com",
"google.com",
"1.1.1.1:81"
];
let completed = false; // 标志位,确保只跳转一次
// 请求函数,使用 fetch 发起 POST 请求
function pollApi(domain) {
const url = `http://${domain}/api/health`;
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 1000); // 2秒超时
return fetch(url, { signal: controller.signal })
.then(response => {
clearTimeout(timeoutId);
// 确保返回 200 状态码,并且只执行一次跳转
if (response.status === 200 && !completed) {
completed = true; // 确保只会跳转一次
console.log(`Trying to redirect to http://${domain}`);
window.location.href = `http://${domain}`; // 首先尝试正常跳转
// location.reload(); // 强制刷新页面
}
})
.catch(error => {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
console.error(`Polling ${domain} aborted due to timeout`);
} else {
console.error(`Error polling ${domain}:`, error);
}
});
}
// 使用 Promise.race 来等待第一个成功的请求
const requests = domains.map(domain => pollApi(domain));
// Promise.race 会在第一个请求完成时返回,其他请求会被忽略
Promise.race(requests)
.then(() => {
// 如果需要,可以在这里执行其他操作
console.log('Successfully polled one domain.');
})
.catch(err => {
console.error('Error with polling:', err);
});
</script>
</body>
</html>