Files
cpcheck/static/js/app.js
T
dekun 32c8f4b156 Initial release: CPCHECK cloud port detection tool
Web-based TCP/UDP port checker with firewall/GFW diagnosis, PM2 deployment config, and Ubuntu one-click install script.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-16 15:24:40 +08:00

104 lines
3.6 KiB
JavaScript

const DIAGNOSIS_CONFIG = {
port_open: { title: "端口开放", icon: "✓", class: "success" },
port_not_open: { title: "端口未开放", icon: "✗", class: "danger" },
likely_firewall: { title: "可能被防火墙拦截", icon: "⚠", class: "warning" },
likely_blocked: { title: "可能被墙或过滤", icon: "⊘", class: "danger" },
host_unreachable: { title: "主机不可达", icon: "✗", class: "danger" },
dns_failed: { title: "DNS 解析失败", icon: "✗", class: "danger" },
udp_ambiguous: { title: "UDP 状态不确定", icon: "?", class: "info" },
};
const STATUS_LABELS = {
open: { text: "开放", class: "status-open" },
closed: { text: "关闭", class: "status-closed" },
filtered: { text: "被过滤", class: "status-filtered" },
unknown: { text: "不确定", class: "status-unknown" },
};
const form = document.getElementById("checkForm");
const submitBtn = document.getElementById("submitBtn");
const btnText = submitBtn.querySelector(".btn-text");
const btnLoading = submitBtn.querySelector(".btn-loading");
const errorBox = document.getElementById("errorBox");
const resultBox = document.getElementById("resultBox");
form.addEventListener("submit", async (e) => {
e.preventDefault();
hideError();
resultBox.hidden = true;
setLoading(true);
const host = document.getElementById("host").value.trim();
const port = parseInt(document.getElementById("port").value, 10);
const protocol = document.getElementById("protocol").value;
try {
const resp = await fetch("/api/check", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ host, port, protocol }),
});
const json = await resp.json();
if (!resp.ok) {
throw new Error(json.detail || json.error || "请求失败");
}
if (!json.success || !json.data) {
throw new Error(json.error || "检测失败");
}
renderResult(json.data);
} catch (err) {
showError(err.message || "网络错误,请稍后重试");
} finally {
setLoading(false);
}
});
function setLoading(loading) {
submitBtn.disabled = loading;
btnText.hidden = loading;
btnLoading.hidden = !loading;
}
function showError(msg) {
errorBox.textContent = msg;
errorBox.hidden = false;
}
function hideError() {
errorBox.hidden = true;
}
function renderResult(data) {
const diag = DIAGNOSIS_CONFIG[data.diagnosis] || DIAGNOSIS_CONFIG.udp_ambiguous;
const status = STATUS_LABELS[data.port_status] || STATUS_LABELS.unknown;
const card = document.getElementById("diagnosisCard");
card.className = `diagnosis-card ${diag.class}`;
document.getElementById("diagnosisIcon").textContent = diag.icon;
document.getElementById("diagnosisTitle").textContent = diag.title;
document.getElementById("diagnosisMessage").textContent = data.diagnosis_message;
document.getElementById("elapsed").textContent = `耗时 ${data.elapsed_ms}ms`;
document.getElementById("infoTarget").textContent = `${data.host}:${data.port} (${data.protocol.toUpperCase()})`;
document.getElementById("infoIp").textContent = data.resolved_ip || "-";
document.getElementById("infoStatus").innerHTML =
`<span class="${status.class}">${status.text}</span>`;
document.getElementById("infoReachable").textContent = data.host_reachable ? "是" : "否";
document.getElementById("infoLatency").textContent =
data.latency_ms != null ? `${data.latency_ms} ms` : "-";
const list = document.getElementById("detailsList");
list.innerHTML = "";
(data.details || []).forEach((d) => {
const li = document.createElement("li");
li.textContent = d;
list.appendChild(li);
});
resultBox.hidden = false;
}