Files
shiroko-monitor/public/index.html
T
tamakyi 6b0a23c38e feat: v0.12.2 —— 跨域只读支持(面板可部署在别处)
用户诉求:管理端与前端完全分离,本地探针只跑 /admin,前端部署到 GitHub Pages
并硬编码管理地址,探测仍在本地常驻。用户自己搭隧道给本地套 HTTPS。

硬限制(务必先看):GitHub Pages 强制 HTTPS,而浏览器「混合内容」策略禁止
HTTPS 页面 fetch HTTP 资源 —— 这与 CORS 无关,改设置也没用。
因此 settings.dataUrl 必须与面板页面同为 HTTPS。

服务端
- 只读接口(/api/status、/api/monitors、/api/events、/api/v2/getMonitors、
  /api/refresh)按 settings.corsOrigins 白名单回显 Access-Control-Allow-Origin
- /api/admin/* 一律不放行跨域,预检直接 403 —— 外部页面既读不到也改不了
- 绝不使用 '*':白名单里写 '*' 不放行任何来源

前端
- settings.dataUrl 存在时,所有 api/ 相对路径自动改写到该地址
- 数据源标记为「远程探针(跨域)」,页脚可区分
- 管理界面新增两项配置:跨域数据源地址、允许跨域的页面地址(改完立即生效)

关键设计:origin 匹配必须考虑端口
origin 是「协议 + 主机 + 端口」的完整组合。最初白名单存 http://localhost(无端口),
导致本地前端跑在 localhost:5173 时被拒 —— 浏览器实测 Failed to fetch 而 curl 能过。
修法:回环主机(localhost / 127.0.0.1)忽略端口放行,其余要求完整 origin 精确匹配。

测试:verify-security 25→40 项,新增 [D3] CORS 白名单 14 条 + [D4] '*' 写法 1 条。
全项目 8 套 334 项通过。

附记一个测试上的教训:跨域 fetch 时 JS 读不到 Access-Control-Allow-Origin
(CORS 规范规定只有同源能读),所以断言「是否放行」要看 fetch 有没有拿到数据,
不能看响应头 —— 我一开始用 headers.get() 判断,拿到 null 误以为失败。
2026-10-14 16:19:31 +08:00

85 lines
3.8 KiB
HTML
Raw 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">
<meta name="description" content="轻量级服务监控面板:HTTP 可用性与 TCP 端口探测">
<title>Shiroko Monitor</title>
<link rel="icon" type="image/svg+xml" href="assets/favicon.svg">
<link rel="stylesheet" href="assets/style.css">
<link rel="stylesheet" href="assets/theme-shiroko.css">
</head>
<body>
<header class="topbar">
<div class="brand">
<span class="logo" aria-hidden="true"></span>
<div class="brand-text">
<h1 id="site-title">Shiroko Monitor</h1>
<p id="site-desc">轻量级服务监控面板</p>
</div>
</div>
<div class="summary">
<span id="overall-pill" class="pill pending">检测中…</span>
<div class="stats">
<div class="stat"><b id="stat-total">–</b><label>监控数</label></div>
<div class="stat stat-up"><b id="stat-up">–</b><label>在线</label></div>
<div class="stat stat-down"><b id="stat-down">–</b><label>离线</label></div>
<div class="stat"><b id="stat-latency">–</b><label>平均延迟</label></div>
<div class="stat"><b id="stat-uptime">–</b><label>90天可用率</label></div>
</div>
<div class="controls">
<div class="view-switch" id="view-switch" role="group" aria-label="视图切换"></div>
<button id="theme-btn" type="button" class="icon-btn" title="切换主题">
<svg viewBox="0 0 100 100" aria-hidden="true">
<circle cx="50" cy="50" r="31" fill="none" stroke="currentColor" stroke-width="8"/>
<circle cx="50" cy="50" r="15" fill="none" stroke="currentColor" stroke-width="4" opacity="0.7"/>
<polygon points="46.4,4 53.6,4 51.2,15 48.8,15" fill="currentColor"/>
<polygon points="46.4,96 53.6,96 51.2,85 48.8,85" fill="currentColor"/>
<polygon points="4,46.4 4,53.6 15,51.2 15,48.8" fill="currentColor"/>
<polygon points="96,46.4 96,53.6 85,51.2 85,48.8" fill="currentColor"/>
</svg>
</button>
<button id="refresh-btn" type="button">刷新</button>
</div>
</div>
</header>
<nav class="group-tabs" id="group-tabs" aria-label="分组筛选"></nav>
<main class="grid" id="monitor-grid">
<div class="empty">正在加载监控配置…</div>
</main>
<!-- 最近事件:故障 / 恢复 / 证书提醒(含维护窗口内的事件) -->
<section class="events" id="events" hidden>
<div class="events-head">
<h2>最近事件</h2>
<span class="events-count" id="events-count"></span>
<button type="button" class="events-more" id="events-more" hidden>展开全部</button>
</div>
<div class="table-wrap events-wrap">
<table class="events-table">
<thead>
<tr><th>时间</th><th>类型</th><th>目标</th><th>详情</th></tr>
</thead>
<tbody id="events-list"></tbody>
</table>
</div>
<p class="events-empty" id="events-empty" hidden>暂无事件记录(故障、恢复与证书提醒会出现在这里)</p>
</section>
<footer class="footer">
<span id="source-badge" class="footer-item">数据源:–</span>
<span id="demo-chip" class="footer-item demo-chip" hidden>演示数据</span>
<span id="ur-chip" class="footer-item warn-chip" hidden>UptimeRobot 同步异常</span>
<span id="notify-badge" class="footer-item" hidden>通知 –</span>
<span id="updated-at" class="footer-item">–</span>
<span id="countdown" class="footer-item">–</span>
<a id="admin-link" class="footer-item admin-link" hidden>管理</a>
<span class="footer-item version">shiroko-monitor v0.12.2</span>
</footer>
<script type="module" src="assets/app.js"></script>
</body>
</html>