90 lines
2.6 KiB
Python
90 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Markmap 本地服务器
|
||
|
||
启动一个简单的 HTTP 服务器,用于本地预览 Markmap 编辑器。
|
||
支持 Python 3.x,无需安装任何额外依赖。
|
||
|
||
用法:
|
||
python serve.py # 默认端口 8080
|
||
python serve.py 3000 # 指定端口 3000
|
||
python serve.py 3000 0.0.0.0 # 绑定到所有网络接口
|
||
"""
|
||
|
||
import http.server
|
||
import socketserver
|
||
import sys
|
||
import os
|
||
import webbrowser
|
||
|
||
# 默认配置
|
||
DEFAULT_PORT = 8080
|
||
DEFAULT_HOST = '127.0.0.1'
|
||
|
||
def main():
|
||
port = DEFAULT_PORT
|
||
host = DEFAULT_HOST
|
||
|
||
# 解析命令行参数
|
||
if len(sys.argv) >= 2:
|
||
try:
|
||
port = int(sys.argv[1])
|
||
except ValueError:
|
||
print(f'无效的端口号: {sys.argv[1]}')
|
||
sys.exit(1)
|
||
if len(sys.argv) >= 3:
|
||
host = sys.argv[2]
|
||
|
||
# 切换到脚本所在目录
|
||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||
os.chdir(script_dir)
|
||
|
||
handler = http.server.SimpleHTTPRequestHandler
|
||
|
||
# 添加 CORS 头和正确的 MIME 类型
|
||
class MarkmapHandler(handler):
|
||
def end_headers(self):
|
||
self.send_header('Access-Control-Allow-Origin', '*')
|
||
self.send_header('Cache-Control', 'no-cache')
|
||
super().end_headers()
|
||
|
||
def guess_type(self, path):
|
||
mimetype = super().guess_type(path)
|
||
# 确保正确的 MIME 类型
|
||
if path.endswith('.mjs') or path.endswith('.js'):
|
||
return 'application/javascript'
|
||
if path.endswith('.css'):
|
||
return 'text/css'
|
||
if path.endswith('.svg'):
|
||
return 'image/svg+xml'
|
||
if path.endswith('.md'):
|
||
return 'text/markdown'
|
||
if path.endswith('.woff2'):
|
||
return 'font/woff2'
|
||
return mimetype
|
||
|
||
try:
|
||
with socketserver.TCPServer((host, port), MarkmapHandler) as httpd:
|
||
url = f'http://{host}:{port}'
|
||
print(f'')
|
||
print(f' Markmap 编辑器已启动')
|
||
print(f' 访问地址: {url}')
|
||
print(f' 按 Ctrl+C 停止服务器')
|
||
print(f'')
|
||
|
||
# 自动打开浏览器
|
||
webbrowser.open(url)
|
||
|
||
httpd.serve_forever()
|
||
except KeyboardInterrupt:
|
||
print(f'\n服务器已停止')
|
||
except OSError as e:
|
||
if e.errno == 48 or 'Address already in use' in str(e):
|
||
print(f'端口 {port} 已被占用,请尝试其他端口')
|
||
else:
|
||
print(f'启动失败: {e}')
|
||
sys.exit(1)
|
||
|
||
if __name__ == '__main__':
|
||
main()
|