Files
ALL-teach_sys/check-status.html
KQL 50557b9230 修复端口状态检测问题
- 改进状态检测算法,使用多种方法组合
- 添加调试工具 check-status.html
- 处理CORS限制问题
- 使用script、image和XMLHttpRequest多种检测方式
2025-09-24 15:12:21 +08:00

248 lines
8.5 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>产业状态检查 - 调试版</title>
<style>
body {
font-family: 'Microsoft YaHei', sans-serif;
padding: 20px;
background: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
border-bottom: 2px solid #667eea;
padding-bottom: 10px;
}
.status-list {
margin-top: 20px;
}
.status-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
margin-bottom: 10px;
background: #f9f9f9;
border-radius: 8px;
border-left: 4px solid #ddd;
}
.status-item.running {
border-left-color: #4caf50;
background: #f1f8e9;
}
.status-item.stopped {
border-left-color: #f44336;
background: #ffebee;
}
.status-item.checking {
border-left-color: #2196f3;
background: #e3f2fd;
}
.port-info {
font-weight: bold;
color: #333;
}
.status-text {
padding: 5px 15px;
border-radius: 15px;
font-size: 14px;
font-weight: 500;
}
.status-text.running {
background: #4caf50;
color: white;
}
.status-text.stopped {
background: #f44336;
color: white;
}
.status-text.checking {
background: #2196f3;
color: white;
}
.refresh-btn {
background: #667eea;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin-top: 20px;
}
.refresh-btn:hover {
background: #5569d0;
}
.log-area {
margin-top: 20px;
padding: 15px;
background: #f5f5f5;
border-radius: 5px;
font-family: monospace;
font-size: 12px;
max-height: 200px;
overflow-y: auto;
}
</style>
</head>
<body>
<div class="container">
<h1>🔍 产业状态检查工具</h1>
<div class="status-list" id="statusList"></div>
<button class="refresh-btn" onclick="checkAllPorts()">刷新状态</button>
<div class="log-area" id="logArea">
<strong>检查日志:</strong><br>
</div>
</div>
<script>
const industries = [
{ name: '文旅产业', port: 5150 },
{ name: '智能制造', port: 5151 },
{ name: '智能开发', port: 5152 },
{ name: '财经商贸', port: 5153 },
{ name: '视觉设计', port: 5154 },
{ name: '交通物流', port: 5155 },
{ name: '大健康', port: 5156 },
{ name: '土木水利', port: 5157 },
{ name: '食品产业', port: 5158 },
{ name: '化工产业', port: 5159 },
{ name: '能源产业', port: 5160 },
{ name: '环保产业', port: 5161 }
];
function addLog(message) {
const logArea = document.getElementById('logArea');
const time = new Date().toLocaleTimeString();
logArea.innerHTML += `[${time}] ${message}<br>`;
logArea.scrollTop = logArea.scrollHeight;
}
function initStatusList() {
const statusList = document.getElementById('statusList');
statusList.innerHTML = industries.map(industry => `
<div class="status-item checking" id="item-${industry.port}">
<div>
<span class="port-info">${industry.name}</span>
<span style="color: #666; margin-left: 10px;">端口: ${industry.port}</span>
</div>
<span class="status-text checking" id="status-${industry.port}">检查中...</span>
</div>
`).join('');
}
async function checkPort(port, name) {
const itemEl = document.getElementById(`item-${port}`);
const statusEl = document.getElementById(`status-${port}`);
addLog(`正在检查 ${name} (端口 ${port})...`);
// 方法1: 使用 fetch 尝试访问
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 3000);
await fetch(`http://localhost:${port}`, {
mode: 'no-cors',
signal: controller.signal,
cache: 'no-cache'
});
clearTimeout(timeoutId);
// 方法2: 使用 Image 对象作为备用检查
return new Promise((resolve) => {
const img = new Image();
const timeout = setTimeout(() => {
addLog(`${name} - 超时,判定为已停止`);
itemEl.className = 'status-item stopped';
statusEl.className = 'status-text stopped';
statusEl.textContent = '已停止';
resolve(false);
}, 2000);
img.onload = () => {
clearTimeout(timeout);
addLog(`${name} - ✅ 运行中`);
itemEl.className = 'status-item running';
statusEl.className = 'status-text running';
statusEl.textContent = '运行中';
resolve(true);
};
img.onerror = () => {
clearTimeout(timeout);
// 方法3: 创建 iframe 测试
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = `http://localhost:${port}`;
const iframeTimeout = setTimeout(() => {
document.body.removeChild(iframe);
addLog(`${name} - 无法连接,可能已停止`);
itemEl.className = 'status-item stopped';
statusEl.className = 'status-text stopped';
statusEl.textContent = '已停止';
resolve(false);
}, 1000);
iframe.onload = () => {
clearTimeout(iframeTimeout);
document.body.removeChild(iframe);
addLog(`${name} - ✅ 运行中通过iframe检测`);
itemEl.className = 'status-item running';
statusEl.className = 'status-text running';
statusEl.textContent = '运行中';
resolve(true);
};
document.body.appendChild(iframe);
};
// 添加时间戳避免缓存
img.src = `http://localhost:${port}/favicon.ico?t=${Date.now()}`;
});
} catch (error) {
addLog(`${name} - 错误: ${error.message}`);
itemEl.className = 'status-item stopped';
statusEl.className = 'status-text stopped';
statusEl.textContent = '已停止';
return false;
}
}
async function checkAllPorts() {
addLog('========== 开始检查所有端口 ==========');
initStatusList();
for (const industry of industries) {
await checkPort(industry.port, industry.name);
// 添加小延迟避免并发过多
await new Promise(resolve => setTimeout(resolve, 100));
}
addLog('========== 检查完成 ==========');
}
// 页面加载时自动检查
window.onload = () => {
checkAllPorts();
};
</script>
</body>
</html>