AirDisk NAS Viewer 通过 HTTP 服务或 Windows 网络驱动器
通过 HTTP 服务或 Windows 网络驱动器,直接访问 AirDisk NAS 上的Tools/index.html文件,便于在浏览器中查看 NAS 中的网页工具。
功能特点
Python 服务器方式:使用
smbprotocol通过 SMB 协议读取文件,无需映射网络驱动器,跨平台运行。Windows 批处理方式:直接映射 NAS 为网络驱动器,然后打开本地文件 URL,适合快速测试。
环境要求
Python 服务器方式
Python 3.7+
网络能访问 NAS 的 SMB 端口(445)
Windows 批处理方式
Windows 操作系统
已开启网络发现和文件共享支持
快速开始
1. 克隆或下载代码
将main.py和start.bat(或自行命名.bat文件)保存到同一目录。
2. 修改配置
打开main.py和.bat文件,根据你的 NAS 实际情况修改以下参数:
| 参数 | 说明 | 示例值 |
|---|---|---|
NAS_HOST | NAS 主机名或 IP | airdisk_xxx或192.168.1.100 |
NAS_SHARE | 共享目录名 | USB-DISK-A |
NAS_USER | SMB 用户名 | Airdisk |
NAS_PASS | SMB 密码 | 123456 |
ENTRY_FILE | 要展示的入口文件(相对路径) | Tools/index.html |
.bat文件中set NAS=...和set USER=...、set PASS=...也要同步修改。
3. 运行
方式 A:Python 服务器(推荐)
# 安装依赖 pip install fastapi uvicorn smbprotocol # 启动服务 python main.py
启动成功后,控制台会显示:
✅ 已连接 airdisk_xxx 🌐 http://localhost:8000
打开浏览器访问http://localhost:8000即可看到Tools/index.html页面,所有相对路径的资源(CSS、JS、图片等)会自动通过/r/路由从 NAS 读取。
方式 B:Windows 批处理
双击运行.bat文件,会自动映射网络驱动器并打开file://airdisk_xxx/USB-DISK-A/Tools/index.html。
注意:该方式依赖 Windows 的
net use命令,且文件以file://协议打开,可能会遇到浏览器跨域或安全限制。
常见问题
Q1: Python 启动时报ModuleNotFoundError: No module named 'smbclient'
A:请运行pip install smbprotocol,它包含了smbclient模块。如果仍然报错,尝试:
pip uninstall smbprotocol pysmbc pip install smbprotocol
Q2: 连接 NAS 失败,提示STATUS_LOGON_FAILURE
A:检查用户名、密码是否正确,NAS 是否允许该用户访问共享,以及主机名/IP 是否可解析(可尝试改用 IP 地址)。
Q3: 入口 HTML 页面加载后,图片/脚本 404
A:检查 HTML 中引用的资源路径是否相对于Tools/目录。服务器已自动添加<base href="/r/Tools/">,通常可以解决。如果资源放在更深目录,请确保路径正确。
Q4: 批处理方式提示“找不到网络路径”
A:确认 NAS 主机名可被 ping 通,或者在C:\Windows\System32\drivers\etc\hosts中添加主机名解析。也可以将NAS变量直接改为\\192.168.x.x\USB-DISK-A。
Q5: 批处理方式打开的页面空白或样式丢失
A:因为file://协议下,许多现代浏览器禁止加载跨驱动器的资源。建议使用 Python 服务器方式以获得完整支持。
文件结构说明
. ├── main.py # FastAPI 服务端程序 ├── start.bat # Windows 批处理脚本(可选)
开发与定制
修改监听端口:编辑
main.py最后一行port=8000。修改资源路由前缀:目前所有资源通过
/r/{path:path}访问,可自行调整。添加 MIME 类型支持:
mimetypes.guess_type()已自动处理常见类型。
代码:
main.py
""" AirDisk NAS Viewer 连接 NAS SMB 共享,直接展示 Tools/index.html 运行: pip install fastapi uvicorn smbprotocol && python main.py """ try: import smbclient except ImportError: raise SystemExit("\n[!] pip install smbprotocol\n") from fastapi import FastAPI, HTTPException from fastapi.responses import HTMLResponse, Response import mimetypes app = FastAPI() # ━━━━━━━ 配置 ━━━━━━━ NAS_HOST = "airdisk_xxx" NAS_SHARE = "USB-DISK-A" NAS_USER = "Airdisk" NAS_PASS = "123456" ENTRY_FILE = "Tools/index.html" # ━━━━━━━━━━━━━━━━━━━━ def smb_path(rel: str) -> str: rel = rel.strip("/").replace("/", "\\") return f"\\\\{NAS_HOST}\\{NAS_SHARE}\\{rel}" if rel else f"\\\\{NAS_HOST}\\{NAS_SHARE}" def safe_path(p: str) -> str: parts = [x for x in p.replace("\\", "/").split("/") if x and x not in ("", "..")] return "/".join(parts) @app.on_event("startup") def startup(): smbclient.register_session(NAS_HOST, username=NAS_USER, password=NAS_PASS) print(f"\n ✅ 已连接 {NAS_HOST}") print(f" 🌐 http://localhost:8000\n") @app.get("/", response_class=HTMLResponse) def index(): try: with smbclient.open_file(smb_path(ENTRY_FILE), mode="rb") as f: content = f.read().decode("utf-8", errors="replace") content = content.replace("</head>", '<base href="/r/Tools/"></head>', 1) return HTMLResponse(content) except Exception as e: raise HTTPException(500, f"读取 {ENTRY_FILE} 失败: {e}") @app.get("/r/{path:path}") def resource(path: str): path = safe_path(path) try: with smbclient.open_file(smb_path(path), mode="rb") as f: content = f.read() mime, _ = mimetypes.guess_type(path) return Response(content, media_type=mime or "application/octet-stream") except Exception as e: raise HTTPException(404, f"找不到: {path}") if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)start.bat
@echo off chcp 65001 >nul 2>&1 set NAS=\\airdisk_xxx\USB-DISK-A set USER=Airdisk set PASS=123456 set URL=file://airdisk_xxx/USB-DISK-A/Tools/index.html net use "%NAS%" /delete /y >nul 2>&1 net use "%NAS%" "%PASS%" /user:"%USER%" /persistent:no if errorlevel 1 ( echo Connection failed. pause exit /b 1 ) echo Connected. Opening... start "" "%URL%" exit /b