Files
Nexus/docs/changelog/2026-05-26-webssh-command-input-bar.md
2026-07-08 22:31:31 +08:00

2.9 KiB
Raw Permalink Blame History

WebSSH 终端命令输入栏

日期: 2026-05-26 变更摘要: 为 WebSSH 终端底部新增命令输入栏,避免直接在 xterm 中逐字符输入导致的显示错乱问题

动机

  1. 用户直接在 xterm 终端中逐字符输入时,SSH echo 与 ANSI prompt 序列交错,导致显示错乱(如 "1111312312oot@mqtele:~#"
  2. 根因:逐字符发送 WebSocket 消息时,read(4096) 返回的数据可能混合 echo 和 prompt 的 ANSI 片段,时序依赖导致渲染错乱
  3. 命令输入栏一次性发送完整命令 + \r,完全避免逐字符 echo 交错问题
  4. 同时提供 Ctrl+C/D 和 Tab 快捷按钮,方便运维操作

变更内容

web/app/terminal.html — 3处修改

修改1: CSS 布局调整

  • 旧:#terminalWrap{height:calc(100vh - 48px)} — 固定高度,终端占满
  • 新:#terminalWrap{flex:1;min-height:0} — flex 弹性布局,为底部命令栏留空间
  • 全屏样式简化:移除 height:100vhflex:1 + fixed inset 自动撑满

修改2: HTML 结构 — 新增命令输入栏

  • terminalWrap 改为 flex flex-col 容器
  • #terminalflex-1 min-h-0 占据剩余空间
  • 新增 #cmdBar 底部栏,包含:
    • 命令提示符
    • <input id="cmdInput"> — 命令输入框,monospace 字体
    • 发送 按钮 — 调用 sendCmd()
    • ⌃C / ⌃D / Tab 快捷按钮 — 分别调用 sendCtrl() / sendKey()

修改3: JavaScript — 命令输入逻辑

  • cmdHistory / cmdHistoryIdx — 命令历史记录 + 上下箭头导航
  • cmdInput keydown — Enter 发送、ArrowUp/Down 浏览历史
  • sendCmd() — 发送完整命令 + \r,记入历史,清空输入框
  • sendCtrl(key) — 发送控制字符(charCode - 96
  • sendKey(key) — 发送原始按键(如 Tab

技术分析

逐字符输入问题:

用户输入 'w' → WS send {type:DATA, data:"w"}
  → SSH echo "\033[...w" → read(4096) 可能返回 "w\033[...root@..."
  → xterm 渲染时 ANSI 序列与 echo 字符交错 → 显示错乱

命令输入栏解决方案:

用户输入 "whoami" → 点发送 → WS send {type:DATA, data:"whoami\r"}
  → SSH 完整回显 "whoami\r\nroot\r\n" → 一次返回 → 正常渲染

涉及文件

  • web/app/terminal.html — 终端页面(CSS + HTML + JS 共3处修改)

是否需迁移/重启

  • 不需重启后端(纯前端改动)
  • 不需 DB 迁移

验证方式

  1. 打开 terminal.html → 底部显示命令输入栏(❯ 提示符 + 输入框 + 发送按钮)
  2. 输入 whoami → 点发送 → 终端显示 root(无显示错乱)
  3. 输入 ls → Enter 键发送 → 正常显示文件列表
  4. ArrowUp → 回显上一条命令 lsArrowDown → 清空
  5. 点击 ⌃C 按钮 → 中断当前命令
  6. 点击 Tab 按钮 → 触发自动补全
  7. 终端 xterm 区域自动占满输入栏上方空间
  8. 全屏模式下输入栏仍然可见