diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 126eca3..a1a0c1c 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -16,7 +16,9 @@ "Bash(git add:*)", "Bash(git rm:*)", "Bash(git push:*)", - "Bash(git commit:*)" + "Bash(git commit:*)", + "Bash(for port in 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161)", + "Bash(do echo -n \"Port $port: \")" ], "deny": [], "ask": [] diff --git a/index.html b/index.html index 201ac95..a902116 100644 --- a/index.html +++ b/index.html @@ -502,98 +502,86 @@ async function checkStatus(port) { const statusEl = document.getElementById(`status-${port}`); - // 使用多种方法检测端口状态 - try { - // 方法1: 创建一个script标签来测试 - const testScript = document.createElement('script'); - testScript.src = `http://localhost:${port}/vite.svg?t=${Date.now()}`; - testScript.onerror = () => { - // 方法2: 使用Image对象检测 - const img = new Image(); - let isResolved = false; + // 默认设置为停止状态 + let isRunning = false; - const checkTimeout = setTimeout(() => { - if (!isResolved) { - isResolved = true; - statusEl.className = 'status status-stopped'; - statusEl.innerHTML = ' 已停止'; - } - }, 2000); + // 创建一个Promise来处理超时 + const checkPromise = new Promise((resolve) => { + // 使用Image对象检测,这是最可靠的跨域方法 + const img = new Image(); + let hasResponded = false; - img.onload = () => { - if (!isResolved) { - isResolved = true; - clearTimeout(checkTimeout); - statusEl.className = 'status status-running'; - statusEl.innerHTML = ' 运行中'; - } - }; + // 设置超时 + const timeout = setTimeout(() => { + if (!hasResponded) { + hasResponded = true; + resolve(false); // 超时则认为服务停止 + } + }, 1500); - img.onerror = () => { - // 方法3: 尝试使用XMLHttpRequest - const xhr = new XMLHttpRequest(); - xhr.open('HEAD', `http://localhost:${port}/`, true); - xhr.timeout = 2000; - - xhr.onreadystatechange = function() { - if (!isResolved && xhr.readyState === 4) { - isResolved = true; - clearTimeout(checkTimeout); - // 即使有CORS错误,如果收到响应就说明服务在运行 - if (xhr.status === 0 || xhr.status === 200) { - // status为0通常表示CORS阻止,但服务器确实响应了 - statusEl.className = 'status status-running'; - statusEl.innerHTML = ' 运行中'; - } else { - statusEl.className = 'status status-stopped'; - statusEl.innerHTML = ' 已停止'; - } - } - }; - - xhr.onerror = function() { - if (!isResolved) { - isResolved = true; - clearTimeout(checkTimeout); - // 网络错误通常意味着服务未运行 - statusEl.className = 'status status-stopped'; - statusEl.innerHTML = ' 已停止'; - } - }; - - try { - xhr.send(); - } catch(e) { - // 发送失败,但这可能是因为CORS - if (!isResolved) { - isResolved = true; - clearTimeout(checkTimeout); - statusEl.className = 'status status-running'; - statusEl.innerHTML = ' 运行中'; - } - } - }; - - // 尝试加载各种可能的静态资源 - const possiblePaths = [ - '/favicon.ico', - '/vite.svg', - '/index.html', - '/assets/index.css' - ]; - - img.src = `http://localhost:${port}${possiblePaths[0]}?t=${Date.now()}`; + img.onload = () => { + if (!hasResponded) { + hasResponded = true; + clearTimeout(timeout); + resolve(true); // 加载成功说明服务运行中 + } }; - testScript.onload = () => { - statusEl.className = 'status status-running'; - statusEl.innerHTML = ' 运行中'; + img.onerror = () => { + if (!hasResponded) { + hasResponded = true; + clearTimeout(timeout); + // 图片加载失败,尝试fetch检测 + fetch(`http://localhost:${port}/`, { + mode: 'no-cors', + cache: 'no-cache' + }).then(() => { + // 如果fetch没有抛出错误,说明服务可能在运行 + // 但由于CORS,我们无法获取响应内容 + // 这种情况下我们需要更谨慎的判断 + + // 创建一个iframe来尝试加载页面 + const iframe = document.createElement('iframe'); + iframe.style.display = 'none'; + iframe.src = `http://localhost:${port}/`; + + const iframeTimeout = setTimeout(() => { + document.body.removeChild(iframe); + resolve(false); // iframe也无法加载,服务停止 + }, 1000); + + iframe.onload = () => { + clearTimeout(iframeTimeout); + document.body.removeChild(iframe); + resolve(true); // iframe加载成功,服务运行中 + }; + + iframe.onerror = () => { + clearTimeout(iframeTimeout); + document.body.removeChild(iframe); + resolve(false); // iframe加载失败,服务停止 + }; + + document.body.appendChild(iframe); + }).catch(() => { + // fetch失败,服务未运行 + resolve(false); + }); + } }; - document.head.appendChild(testScript); - setTimeout(() => document.head.removeChild(testScript), 100); + // 尝试加载favicon或vite.svg + img.src = `http://localhost:${port}/vite.svg?t=${Date.now()}`; + }); - } catch (error) { + // 等待检测结果 + isRunning = await checkPromise; + + // 更新UI + if (isRunning) { + statusEl.className = 'status status-running'; + statusEl.innerHTML = ' 运行中'; + } else { statusEl.className = 'status status-stopped'; statusEl.innerHTML = ' 已停止'; } diff --git a/status-checker.html b/status-checker.html new file mode 100644 index 0000000..2440c25 --- /dev/null +++ b/status-checker.html @@ -0,0 +1,189 @@ + + +
+ + +