通过 HTTP 服务或 Windows 网络驱动器直接访问 AirDisk NAS 上的Tools/index.html文件便于在浏览器中查看 NAS 中的网页工具。功能特点Python 服务器方式使用smbprotocol通过 SMB 协议读取文件无需映射网络驱动器跨平台运行。Windows 批处理方式直接映射 NAS 为网络驱动器然后打开本地文件 URL适合快速测试。环境要求Python 服务器方式Python 3.7网络能访问 NAS 的 SMB 端口445Windows 批处理方式Windows 操作系统已开启网络发现和文件共享支持快速开始1. 克隆或下载代码将main.py和start.bat或自行命名.bat文件保存到同一目录。2. 修改配置打开main.py和.bat文件根据你的 NAS 实际情况修改以下参数参数说明示例值NAS_HOSTNAS 主机名或 IPairdisk_xxx或192.168.1.100NAS_SHARE共享目录名USB-DISK-ANAS_USERSMB 用户名AirdiskNAS_PASSSMB 密码123456ENTRY_FILE要展示的入口文件相对路径Tools/index.html.bat文件中set NAS...和set USER...、set PASS...也要同步修改。3. 运行方式 APython 服务器推荐# 安装依赖 pip install fastapi uvicorn smbprotocol # 启动服务 python main.py启动成功后控制台会显示✅ 已连接 airdisk_xxx http://localhost:8000打开浏览器访问http://localhost:8000即可看到Tools/index.html页面所有相对路径的资源CSS、JS、图片等会自动通过/r/路由从 NAS 读取。方式 BWindows 批处理双击运行.bat文件会自动映射网络驱动器并打开file://airdisk_xxx/USB-DISK-A/Tools/index.html。注意该方式依赖 Windows 的net use命令且文件以file://协议打开可能会遇到浏览器跨域或安全限制。常见问题Q1: Python 启动时报ModuleNotFoundError: No module named smbclientA:请运行pip install smbprotocol它包含了smbclient模块。如果仍然报错尝试pip uninstall smbprotocol pysmbc pip install smbprotocolQ2: 连接 NAS 失败提示STATUS_LOGON_FAILUREA:检查用户名、密码是否正确NAS 是否允许该用户访问共享以及主机名/IP 是否可解析可尝试改用 IP 地址。Q3: 入口 HTML 页面加载后图片/脚本 404A:检查 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最后一行port8000。修改资源路由前缀目前所有资源通过/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, usernameNAS_USER, passwordNAS_PASS) print(f\n ✅ 已连接 {NAS_HOST}) print(f http://localhost:8000\n) app.get(/, response_classHTMLResponse) def index(): try: with smbclient.open_file(smb_path(ENTRY_FILE), moderb) as f: content f.read().decode(utf-8, errorsreplace) 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), moderb) as f: content f.read() mime, _ mimetypes.guess_type(path) return Response(content, media_typemime or application/octet-stream) except Exception as e: raise HTTPException(404, f找不到: {path}) if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8000)start.batecho off chcp 65001 nul 21 set NAS\\airdisk_xxx\USB-DISK-A set USERAirdisk set PASS123456 set URLfile://airdisk_xxx/USB-DISK-A/Tools/index.html net use %NAS% /delete /y nul 21 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
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 端口445Windows 批处理方式Windows 操作系统已开启网络发现和文件共享支持快速开始1. 克隆或下载代码将main.py和start.bat或自行命名.bat文件保存到同一目录。2. 修改配置打开main.py和.bat文件根据你的 NAS 实际情况修改以下参数参数说明示例值NAS_HOSTNAS 主机名或 IPairdisk_xxx或192.168.1.100NAS_SHARE共享目录名USB-DISK-ANAS_USERSMB 用户名AirdiskNAS_PASSSMB 密码123456ENTRY_FILE要展示的入口文件相对路径Tools/index.html.bat文件中set NAS...和set USER...、set PASS...也要同步修改。3. 运行方式 APython 服务器推荐# 安装依赖 pip install fastapi uvicorn smbprotocol # 启动服务 python main.py启动成功后控制台会显示✅ 已连接 airdisk_xxx http://localhost:8000打开浏览器访问http://localhost:8000即可看到Tools/index.html页面所有相对路径的资源CSS、JS、图片等会自动通过/r/路由从 NAS 读取。方式 BWindows 批处理双击运行.bat文件会自动映射网络驱动器并打开file://airdisk_xxx/USB-DISK-A/Tools/index.html。注意该方式依赖 Windows 的net use命令且文件以file://协议打开可能会遇到浏览器跨域或安全限制。常见问题Q1: Python 启动时报ModuleNotFoundError: No module named smbclientA:请运行pip install smbprotocol它包含了smbclient模块。如果仍然报错尝试pip uninstall smbprotocol pysmbc pip install smbprotocolQ2: 连接 NAS 失败提示STATUS_LOGON_FAILUREA:检查用户名、密码是否正确NAS 是否允许该用户访问共享以及主机名/IP 是否可解析可尝试改用 IP 地址。Q3: 入口 HTML 页面加载后图片/脚本 404A:检查 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最后一行port8000。修改资源路由前缀目前所有资源通过/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, usernameNAS_USER, passwordNAS_PASS) print(f\n ✅ 已连接 {NAS_HOST}) print(f http://localhost:8000\n) app.get(/, response_classHTMLResponse) def index(): try: with smbclient.open_file(smb_path(ENTRY_FILE), moderb) as f: content f.read().decode(utf-8, errorsreplace) 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), moderb) as f: content f.read() mime, _ mimetypes.guess_type(path) return Response(content, media_typemime or application/octet-stream) except Exception as e: raise HTTPException(404, f找不到: {path}) if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8000)start.batecho off chcp 65001 nul 21 set NAS\\airdisk_xxx\USB-DISK-A set USERAirdisk set PASS123456 set URLfile://airdisk_xxx/USB-DISK-A/Tools/index.html net use %NAS% /delete /y nul 21 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