# Web Tools 一个匿名访问、自托管的浏览器本地工具箱。支持多人同时使用;除全局导航顺序外,文本、密钥、文件、图片和计算结果均只存在于各自浏览器中,不会发送到服务端。 当前应用版本:`0.0.6`。 ## 内置工具 - ASCII/UTF-8 与 Hex 互转 - Base64 与 Base64 URL 编码、解码,解码结果支持 UTF-8、连续 Hex 和代码字节数组 - AES-128-CMAC(RFC 4493) - CRC-8/16/32/64 预设与自定义参数,支持 BIN 和多 block Intel HEX - 固件 SHA-256 / SHA-512,支持 Intel HEX 有效数据和带地址/长度的 Block 校验头 - RSA 2048/3072/4096 位密钥对,导出 PEM,以及可分别复制的 N/E Hex 或代码字节数组 - 密码学安全随机数,支持连续 Hex、空格 Hex 和代码字节数组 - JSON 格式化、压缩、校验和语法着色 - XML 格式化、压缩、校验和语法着色 - PNG 转多尺寸 ICO ## 交付物与源码 容器交付 ZIP 同时包含源码、测试、生产构建结果和部署文件,不是只有压缩后的网页。主要目录如下: ```text src/ Vue 3 前端源码 components/ 所有工具共用的 UI 组件 lib/ 可测试的纯计算与浏览器辅助逻辑 tools/ 每个工具一个独立 Vue 组件 workers/ 大文件计算使用的浏览器后台线程 views/SettingView.vue /setting 工具管理页 server/ 零依赖 Node.js 静态服务和导航配置 API shared/tool-catalog.json 工具与分类的权威元数据目录 shared/default-navigation.json 新部署的默认分类和工具顺序 tests/ Vitest 单元测试 dist/ npm run build 生成的生产前端 Dockerfile 多阶段容器构建 docker-compose.yml 默认部署配置 THIRD_PARTY_NOTICES.md 第三方依赖许可说明 CHANGELOG.md 版本变更、修复和验证记录 ``` 交付包不包含 `node_modules`。Docker 首次构建需要访问 Node 镜像仓库和 npm 软件源;若环境完全离线,应另外交付 Docker 镜像 tar。 ## 架构约束 - Vue 3、TypeScript、Vite 前端;Node.js 标准库服务端;不引入数据库。 - 工具组件彼此独立并懒加载,公共交互使用 `ToolPage`、`ModeTabs`、`TextEditor` 和 `src/styles.css` 中的现有样式。 - 工具的计算、解析和文件生成逻辑放在 `src/lib/`,Vue 组件只负责状态与交互。 - 大文件或长时间计算必须放入 `src/workers/` 的 Web Worker,避免阻塞页面交互;Worker 仍只在浏览器本地处理数据。 - 路由和左侧导航由工具目录自动生成,增加普通工具时不得手工新增路由。 - 工具输入只在浏览器内存中处理,不得发送给服务端、遥测服务或第三方接口。 - 服务端只持久化导航顺序,文件为 `/data/navigation.json`,写入采用临时文件和原子替换。 - `/setting` 是固定但不公开显示的管理入口;项目没有登录、收藏、赞助或用户系统。 - 页面必须保持统一 UI,并兼容桌面端和移动端竖屏。 ## 多人使用与状态边界 - 每个浏览器标签页拥有独立的 Vue 组件状态、文件对象、图像对象和 Web Worker。不同用户、浏览器或标签页不会共享工具输入与结果。 - CRC、固件 Hash、RSA、AES-CMAC、随机数、PNG/ICO、编码转换和格式化都在浏览器中执行;服务端没有工具计算接口。 - `/setting` 保存的是所有访问者共享的导航配置。并发保存没有版本冲突合并,最后完成原子替换的请求生效。 - 原子替换保证读取者看到完整的旧配置或新配置,不会看到写到一半的 JSON;它不保证保留多个用户各自的排序修改。 - 已打开的页面不会实时接收其他用户保存的新顺序,刷新或重新打开后才会读取。 - 深浅主题保存在当前浏览器同源 `localStorage` 中;系统剪贴板由操作系统管理。这两项不会改变工具计算结果。 ## 资源限制 限制用于避免异常文件、解压后超大图像或高密度语法 token 长时间占用浏览器。修改这些数值时必须同步源码常量、测试和本文档。 | 功能 | 当前限制 | 超限行为 | | --- | --- | --- | | CRC 固件文件 | 最大 64 MiB | 选择时拒绝,不保留旧文件结果 | | Intel HEX 非空记录 | 最多 500,000 条 | Worker 停止解析并显示错误 | | Intel HEX 数据块 | 最多 1,024 个 block | Worker 停止解析并显示错误 | | 固件 Hash 文件及有效数据 | 文件最大 64 MiB,有效数据最大 64 MiB | 选择或计算时拒绝 | | PNG 压缩文件 | 最大 32 MiB | 创建预览前拒绝 | | PNG 尺寸 | 单边最大 16,384 像素,总计最大 32,000,000 像素 | 浏览器解码前拒绝 | | 安全随机数 | 每次 1 至 65,536 字节 | 拒绝无效长度 | | JSON/XML 语法着色 | 最大 100,000 字符且不超过 10,000 个 token | 结果仍完整显示,但降级为纯文本以减少 DOM 节点 | | 导航配置请求体 | 最大 64 KiB | 服务端返回 400 | ## Docker Compose 部署 要求 Linux AMD64/ARM64、Docker Engine 24+、Docker Compose v2。 ```bash docker compose up -d --build ``` 默认访问地址:`http://服务器地址:8080` 自定义端口: ```bash WEB_TOOLS_PORT=9000 docker compose up -d --build ``` 检查状态: ```bash docker compose ps docker compose logs --tail=100 web-tools ``` 停止服务: ```bash docker compose down ``` 导航配置保存在 Docker 卷 `web-tools-data` 中的 `/data/navigation.json`。全新部署且从未保存过排序时,应用直接使用内置默认配置,该文件可能尚不存在;首次保存后会创建。删除或重建容器不会丢失已有配置,执行 `docker compose down -v` 才会删除该卷。 健康检查地址:`http://服务器地址:8080/healthz` ## Windows Server 部署(不使用 Docker) 要求安装 Git、Node.js 22.12.0 或更高版本,并使用 PowerShell 5.1 或更高版本。以下示例假设项目位于 `C:\Services\WebTools`。 首次克隆后安装依赖并构建: ```powershell Set-Location C:\Services\WebTools npm.cmd ci --include=dev npm.cmd run build ``` 生产构建成功后,使用项目根目录的统一脚本启动: ```powershell powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\web-tools.ps1 start ``` 默认监听 `0.0.0.0:9000`,导航配置保存在 `C:\ProgramData\WebTools\data\navigation.json`。可以通过参数覆盖: ```powershell powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\web-tools.ps1 start ` -ListenAddress 127.0.0.1 ` -Port 8080 ` -DataDir C:\ProgramData\WebTools\data ``` 从 Git `main` 分支更新时,先在运行窗口按 `Ctrl+C` 停止服务,再执行: ```powershell powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\web-tools.ps1 update ``` 更新脚本只接受干净的 Git 工作区和当前 `main` 分支,使用 `git pull --ff-only origin main` 避免隐式合并。随后执行 `npm ci --include=dev`、生产构建并自动重新启动服务。`npm ci` 会先删除现有 `node_modules` 再按 `package-lock.json` 完整重建,不需要手工删除旧依赖。只更新和构建、不立即启动时增加 `-NoStart`。 脚本不会读取、覆盖或删除 `C:\ProgramData\WebTools\data`。PowerShell 窗口关闭后前台服务会停止;如使用 Windows 计划任务,应让任务执行 `web-tools.ps1 start`,更新时停止任务、运行 `web-tools.ps1 update -NoStart`,然后重新启动任务。 ## 工具管理 管理入口不显示在页面中,直接访问: ```text http://服务器地址:8080/setting ``` 可以调整分类顺序、分类内工具顺序及工具所属分类。保存时采用同目录临时文件和原子替换。 导出配置(至少保存过一次排序后执行): ```bash docker compose cp web-tools:/data/navigation.json ./navigation.json ``` 导入配置: ```bash docker compose cp ./navigation.json web-tools:/data/navigation.json docker compose restart web-tools ``` 升级应用前建议导出该文件。新版本增加工具时,服务端会保留已有顺序,并把缺少的新工具追加到其默认分类。 ## 离线镜像 若交付目录包含 `personal-web-tools-0.0.6-amd64.tar`,可直接导入: ```bash docker load -i personal-web-tools-0.0.6-amd64.tar docker compose up -d --no-build ``` 当前源码 ZIP 本身不是 Docker 镜像 tar。 ## 本地开发 要求 Node.js 22.12.0 或更高版本。首次安装使用锁定依赖: ```bash npm ci ``` 终端一运行配置服务: ```bash PORT=8081 DATA_DIR=./data node server/index.mjs ``` 终端二运行 Vite;`/api` 和 `/healthz` 会代理到 `127.0.0.1:8081`: ```bash npm run dev ``` 生产模式本地运行: ```bash npm run build npm start ``` 生产服务默认监听 `0.0.0.0:8080`。 完整工程检查: ```bash npm run check npm audit --audit-level=low ``` `npm run check` 会依次运行全部 Vitest 测试、TypeScript/Vue 类型检查和生产构建。服务端测试使用随机本地端口验证 SPA 直达路由、静态资源 404、导航 API、请求大小限制及跨站写入拦截。 自动化测试还覆盖标准算法向量、Base64 规范性、Intel HEX 记录与 block 边界、固件 Hash 与大小端 Block 头向量、PNG 头部与像素限制、导航排序纯函数、目录/图标/懒加载组件一致性,以及原子写入失败后的临时文件清理。 ## 增加工具 ### 固件 Hash 固定语义 固件 Hash 与 CRC 共用经过校验的 Intel HEX 解析器,但使用独立纯逻辑、Worker 和 Vue 页面。解析器处理扩展段/线性地址,将数据按 32 位绝对地址排序,合并连续记录,去重内容一致的重叠记录,并拒绝冲突或越过 `0xFFFFFFFF` 的数据。记录文本、记录校验和、EOF 和启动地址不参与 Hash。 “有效数据”模式的总输入为所有 block 数据按地址升序直接拼接,不填充地址空洞。“Block 校验头”模式在每个 block 前加入 8 个二进制字节: ```text uint32 startAddress uint32 dataLength ``` 默认使用 Big Endian,可以显式切换 Little Endian。两个字段始终为 4 字节;`dataLength` 只表示该 block 的有效数据字节数,不包含 8 字节校验头。总输入严格为 `Header1 || Data1 || Header2 || Data2 ...`,同时输出总 SHA-256/SHA-512 和每个 block 的独立摘要。不得把固定宽度 Hex 文本误作为 ASCII 字符加入 Hash,也不得隐式使用运行设备的原生端序。 ### 1. 先定义稳定标识 为工具选择永久的 kebab-case `id`,例如 `url-encode`。已发布工具的 `id` 不应修改,因为路由、懒加载映射和用户保存的导航配置都依赖它。 确定工具所属分类。新增分类时,需要同时更新: - `shared/tool-catalog.json` 中的 `categories` - `shared/default-navigation.json` 中的 `categories` 仅新增工具时,分类配置版本仍保持 `version: 1`,不要因为工具数量变化而升级配置格式版本。 ### 2. 编写独立计算逻辑 将编码、解析、加密、校验或文件生成逻辑放入 `src/lib/`。优先使用浏览器标准 API或经过验证的现有依赖,不在 Vue 组件中堆积算法实现。 在 `tests/` 添加正常输入、边界输入、无效输入和已知测试向量。涉及字节的工具必须明确 UTF-8、Hex、Base64、换行及分隔符语义,避免隐式改变数据。 文件或高开销工具还必须定义文件大小、记录数量、图像尺寸或输出 DOM 数量等资源上限。异步工具在清空、更换输入或卸载后必须忽略旧任务结果;计算量较大的文件解析与 CRC 计算放入 Web Worker。 ### 3. 编写统一的工具页面 在 `src/tools/` 新增一个 Vue 组件,并参考现有 `Base64Tool.vue` 或与需求最接近的工具。 - 页面外层使用 `ToolPage`。 - 文本输入输出优先使用 `TextEditor`。 - 模式切换使用 `ModeTabs`。 - 操作按钮使用 Lucide 图标和现有 `action-button` 类。 - 必须提供清空、错误提示和必要的复制/粘贴操作。 - 不增加登录、收藏、赞助、遥测、外部网络请求或独立视觉风格。 - 在窄屏下确认控件不溢出、不重叠,文字不会遮挡。 ### 4. 登记工具元数据 在 `shared/tool-catalog.json` 的 `tools` 中增加: ```json { "id": "url-encode", "title": "URL 编解码", "category": "encoding", "description": "编码和解码 URL 组件。", "icon": "Link" } ``` `id` 必须唯一,`category` 必须存在。`icon` 使用 Lucide Vue 图标名称。 在 `shared/default-navigation.json` 的目标分类工具数组中加入相同 `id`,位置即新部署的默认显示顺序。 ### 5. 注册图标与懒加载组件 在 `src/tools/registry.ts` 中完成三件事: 1. 从 `@lucide/vue` 导入目录中填写的图标。 2. 把图标加入 `iconComponents`。 3. 把工具 `id` 和 `defineAsyncComponent(() => import(...))` 加入 `toolComponents`。 工具目录、默认导航和注册表中的 `id` 必须完全一致。路由会从注册表自动生成,不需要修改 `src/router.ts`。 现有自动化测试会校验目录分类、工具 ID、图标注册和懒加载组件映射。新增工具后若漏改任一处,`npm test` 或应用启动会直接报错。 ### 6. 验证兼容性 ```bash npm run check npm audit --audit-level=low ``` 还应在真实浏览器中检查: - 新工具的默认路径 `/tools/` 可以直接打开和刷新。 - 左侧导航、搜索和 `/setting` 正常显示新工具。 - 已保存的旧 `navigation.json` 启动后会自动补入新工具。 - 桌面端和约 `390 x 844` 的移动端竖屏布局正常。 - 浏览器控制台无错误,工具内容没有发往服务端。 ## AI 接手清单 后续由 AI 增加或修改工具时,应先阅读本文件,然后依次检查: 1. `shared/tool-catalog.json` 和 `shared/default-navigation.json` 2. `src/tools/registry.ts` 3. 与目标功能最接近的 `src/tools/*.vue` 4. `src/components/ToolPage.vue`、`TextEditor.vue`、`ModeTabs.vue` 5. 相关 `src/lib/` 和 `tests/` 6. `server/navigation.mjs` 中的导航兼容逻辑 AI 不应仅修改 `dist/`;必须修改源码并重新构建。不得覆盖或删除用户的 `data/navigation.json`。发现工作区已有未说明的改动时应保留并兼容,不得擅自回退。 处理多人访问、文件工具或异步计算时,还必须检查本文档中的“多人使用与状态边界”和“资源限制”,避免重新引入共享状态、旧任务覆盖新输入或无上限解析。 完成任务后至少报告:修改的工具、数据格式选择、测试和构建结果、容器包路径及 SHA-256。涉及 UI 的改动还要进行桌面和移动端浏览器验收。 ## 版本与发布 应用版本的权威来源是 `package.json`。发布新版本时: 1. 使用 `npm version patch --no-git-tag-version` 或按兼容性选择 minor/major,使 `package.json` 与 `package-lock.json` 同步。 2. 更新 `docker-compose.yml` 中的镜像标签。 3. 更新本文档中的当前版本和离线镜像文件名。 4. 在 `CHANGELOG.md` 记录用户可见变更、重要修复和验证结果。 5. 运行测试、生产构建和依赖审计。 6. 重新制作源码/容器部署 ZIP,并生成 SHA-256。 版本号固定显示在左侧导航底部;版权信息 `Copyright © mid All Rights Reserved.` 固定显示在所有页面底部。第三方许可保留在 `THIRD_PARTY_NOTICES.md`。 ## 安全边界 - 无登录、无统计、无遥测、无 CDN 和第三方网络请求。 - `/setting` 是固定但不显示的入口,不构成身份认证;直接公开到互联网时任何访问者都可能修改排序。 - 工具内容仅在浏览器内存中处理,默认不会持久化。 - 容器以非 root 用户运行,根文件系统只读,全部 Linux capabilities 已移除。 - 服务端只接受不超过 64 KiB 的导航 JSON 配置。 - 服务端只提供静态文件、`GET/PUT /api/navigation` 和 `GET /healthz`。 - 只有无扩展名且明确请求 HTML 的前端路由会回退到 `index.html`;缺失的 JS、CSS 和其他资源返回 404。 - JSON API 响应使用 `Cache-Control: no-store`,避免浏览器缓存导航和健康状态。 - 安全响应头禁止第三方脚本、跨站嵌入、摄像头、麦克风和定位权限。