fix: serve local vue assets
This commit is contained in:
parent
bfe41148d8
commit
f33e07d4f3
45
server.py
45
server.py
@ -157,42 +157,61 @@ class MonitorHandler(BaseHTTPRequestHandler):
|
||||
return
|
||||
|
||||
def do_GET(self) -> None: # noqa: N802
|
||||
self._dispatch(send_body=True)
|
||||
|
||||
def do_HEAD(self) -> None: # noqa: N802
|
||||
self._dispatch(send_body=False)
|
||||
|
||||
def _dispatch(self, send_body: bool) -> None:
|
||||
parsed = urlparse(self.path)
|
||||
if parsed.path in {"/", "/index.html"}:
|
||||
return self.serve_static("index.html", "text/html; charset=utf-8")
|
||||
return self.serve_static("index.html", "text/html; charset=utf-8", send_body=send_body)
|
||||
if parsed.path == "/app.css":
|
||||
return self.serve_static("app.css", "text/css; charset=utf-8")
|
||||
return self.serve_static("app.css", "text/css; charset=utf-8", send_body=send_body)
|
||||
if parsed.path == "/app.js":
|
||||
return self.serve_static("app.js", "application/javascript; charset=utf-8")
|
||||
return self.serve_static("app.js", "application/javascript; charset=utf-8", send_body=send_body)
|
||||
if parsed.path == "/vue.js":
|
||||
return self.serve_static("vue.js", "application/javascript; charset=utf-8", send_body=send_body)
|
||||
if parsed.path == "/api/health":
|
||||
return self.send_payload(HTTPStatus.OK, response_json({"status": "ok", "time": utc_now()}), "application/json; charset=utf-8")
|
||||
return self.send_payload(
|
||||
HTTPStatus.OK,
|
||||
response_json({"status": "ok", "time": utc_now()}),
|
||||
"application/json; charset=utf-8",
|
||||
send_body=send_body,
|
||||
)
|
||||
if parsed.path == "/api/monitor/services":
|
||||
payload = get_monitor_payload()
|
||||
return self.send_payload(HTTPStatus.OK, response_json(payload), "application/json; charset=utf-8")
|
||||
return self.send_payload(
|
||||
HTTPStatus.OK,
|
||||
response_json(payload),
|
||||
"application/json; charset=utf-8",
|
||||
send_body=send_body,
|
||||
)
|
||||
if parsed.path == "/favicon.ico":
|
||||
return self.send_payload(HTTPStatus.NO_CONTENT, b"", "image/x-icon")
|
||||
return self.send_error_payload(HTTPStatus.NOT_FOUND, "not found")
|
||||
return self.send_payload(HTTPStatus.NO_CONTENT, b"", "image/x-icon", send_body=send_body)
|
||||
return self.send_error_payload(HTTPStatus.NOT_FOUND, "not found", send_body=send_body)
|
||||
|
||||
def serve_static(self, name: str, content_type: str) -> None:
|
||||
def serve_static(self, name: str, content_type: str, send_body: bool) -> None:
|
||||
path = STATIC_DIR / name
|
||||
if not path.exists():
|
||||
return self.send_error_payload(HTTPStatus.NOT_FOUND, "static file missing")
|
||||
self.send_payload(HTTPStatus.OK, path.read_bytes(), content_type)
|
||||
return self.send_error_payload(HTTPStatus.NOT_FOUND, "static file missing", send_body=send_body)
|
||||
self.send_payload(HTTPStatus.OK, path.read_bytes(), content_type, send_body=send_body)
|
||||
|
||||
def send_error_payload(self, status: HTTPStatus, message: str) -> None:
|
||||
def send_error_payload(self, status: HTTPStatus, message: str, send_body: bool) -> None:
|
||||
self.send_payload(
|
||||
status,
|
||||
response_json({"status": int(status), "error": message}),
|
||||
"application/json; charset=utf-8",
|
||||
send_body=send_body,
|
||||
)
|
||||
|
||||
def send_payload(self, status: HTTPStatus, body: bytes, content_type: str) -> None:
|
||||
def send_payload(self, status: HTTPStatus, body: bytes, content_type: str, send_body: bool) -> None:
|
||||
self.send_response(status)
|
||||
self.send_header("Content-Type", content_type)
|
||||
self.send_header("Cache-Control", "no-store")
|
||||
self.send_header("Content-Length", str(len(body)))
|
||||
self.end_headers()
|
||||
if body:
|
||||
if send_body and body:
|
||||
self.wfile.write(body)
|
||||
|
||||
|
||||
|
||||
@ -94,6 +94,14 @@ createApp({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const root = document.getElementById("app");
|
||||
const bootIndicator = document.getElementById("boot-indicator");
|
||||
if (root) {
|
||||
root.removeAttribute("v-cloak");
|
||||
}
|
||||
if (bootIndicator) {
|
||||
bootIndicator.hidden = true;
|
||||
}
|
||||
this.refresh();
|
||||
this.timer = window.setInterval(() => this.refresh(), 10000);
|
||||
},
|
||||
|
||||
@ -1,14 +1,26 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>HY App Monitor</title>
|
||||
<link rel="stylesheet" href="/app.css" />
|
||||
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
|
||||
<script defer src="/vue.js"></script>
|
||||
<script defer src="/app.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="boot-indicator" class="boot-indicator">
|
||||
<strong>HY App Monitor</strong>
|
||||
<span>正在加载页面资源,请稍候。</span>
|
||||
</div>
|
||||
<noscript>
|
||||
<div class="boot-indicator noscript-indicator">
|
||||
<strong>浏览器已禁用 JavaScript</strong>
|
||||
<span>当前页面依赖脚本渲染,请启用 JavaScript 后再访问。</span>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="app" v-cloak class="shell">
|
||||
<header class="hero">
|
||||
<div class="hero-copy">
|
||||
@ -37,9 +49,12 @@
|
||||
<section class="toolbar">
|
||||
<div class="toolbar-left">
|
||||
<button :class="['filter-chip', filter === 'all' ? 'active' : '']" @click="filter = 'all'">全部</button>
|
||||
<button :class="['filter-chip', filter === 'down' ? 'active' : '']" @click="filter = 'down'">只看异常</button>
|
||||
<button :class="['filter-chip', filter === 'java' ? 'active' : '']" @click="filter = 'java'">Java</button>
|
||||
<button :class="['filter-chip', filter === 'golang' ? 'active' : '']" @click="filter = 'golang'">Golang</button>
|
||||
<button :class="['filter-chip', filter === 'down' ? 'active' : '']"
|
||||
@click="filter = 'down'">只看异常</button>
|
||||
<button :class="['filter-chip', filter === 'java' ? 'active' : '']"
|
||||
@click="filter = 'java'">Java</button>
|
||||
<button :class="['filter-chip', filter === 'golang' ? 'active' : '']"
|
||||
@click="filter = 'golang'">Golang</button>
|
||||
</div>
|
||||
<div class="toolbar-right">
|
||||
<input v-model.trim="keyword" class="search" placeholder="搜索主机 / 服务 / IP" />
|
||||
@ -104,4 +119,5 @@
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
13
static/vue.js
Normal file
13
static/vue.js
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user