# 利用客户端随机跳转

* 再配合JS加密，效果更好

```markup
<!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>

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://close.gitbook.io/yun-wei-bi-ji/centos/nginx/li-yong-ke-hu-duan-sui-ji-tiao-zhuan.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
