53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
支持 SPA 路由的静态文件服务器
|
|
将所有 404 请求重定向到 index.html
|
|
"""
|
|
import http.server
|
|
import socketserver
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
PORT = 10000
|
|
DIRECTORY = Path(__file__).parent / "frontend" / "dist"
|
|
|
|
class SPAHandler(http.server.SimpleHTTPRequestHandler):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, directory=str(DIRECTORY), **kwargs)
|
|
|
|
def log_message(self, format, *args):
|
|
# 简化日志输出
|
|
sys.stderr.write(f"[{self.log_date_time_string()}] {args[0]}\n")
|
|
|
|
def do_GET(self):
|
|
# 检查请求的文件是否存在
|
|
file_path = DIRECTORY / self.path.lstrip('/').split('?')[0]
|
|
|
|
# 如果文件不存在且不是静态资源,返回 index.html
|
|
if not file_path.exists() and not self.path.startswith('/assets/'):
|
|
self.path = '/index.html'
|
|
|
|
return super().do_GET()
|
|
|
|
def end_headers(self):
|
|
self.send_header('Access-Control-Allow-Origin', '*')
|
|
super().end_headers()
|
|
|
|
class ReusableTCPServer(socketserver.TCPServer):
|
|
allow_reuse_address = True
|
|
daemon_threads = True
|
|
|
|
if __name__ == "__main__":
|
|
os.chdir(DIRECTORY)
|
|
sys.stdout.write(f"🚀 SPA Server starting at http://0.0.0.0:{PORT}\n")
|
|
sys.stdout.write(f"📁 Serving: {DIRECTORY}\n")
|
|
sys.stdout.write("✓ SPA routing enabled (404s -> index.html)\n")
|
|
sys.stdout.flush()
|
|
|
|
try:
|
|
with ReusableTCPServer(("0.0.0.0", PORT), SPAHandler) as httpd:
|
|
httpd.serve_forever()
|
|
except KeyboardInterrupt:
|
|
sys.stdout.write("\n👋 Server stopped\n")
|