mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 12:30:44 +00:00
🚨 修一个严重 bug:管理页所有按钮又失效了(同一个坑踩第二次)
== 症状 ==
在**真实中转**上实测管理页时,用 node --check 检查页面内嵌的 JS:
SyntaxError: Invalid or unexpected token (第 46 行)
整段 <script> 不执行 -> 改码 / 删除 / 批量删除 / 全选 全部变幽灵按键。
**这正是用户之前报过的那个 bug,加新功能时又踩了一遍。**
== 根因(讽刺到极点)==
admin.py 的 ADMIN_JS 是**普通三引号字符串**,里面写一个反斜杠+n
会被 Python 解释成**真实换行**。而 JS 的行注释 // 不能跨行 ——
一断行,后面就成了裸文本,整段脚本语法错误。
出事的是这段注释:
// ⚠ 这里必须是 \\n(反斜杠+n),不能是 \n ——
^^^^
这个 \n 被 Python 变成真换行
**注释为了举例说明「不能写 \n」,自己写了一个 \n。**
于是注释被断成两行,把整段 JS 弄坏了。
== 修法 ==
注释改成**一个转义序列都不写**,只用文字描述:
// ⚠ 下面 prompt 里的换行,必须写成「反斜杠 + n」两个字符。
// 本文件是普通三引号字符串:只写反斜杠 + n,Python 会把它
// 变成**真实换行** ... (一个转义都不出现)
并把"踩过两次"的历史写进注释,提醒后人别再来第三次。
== 新增两个测试(防止再犯)==
1. `_tests/test_admin_js_syntax.py`(已注册为回归阶段 3a6)
**本地渲染管理页**,把 <script> 抠出来喂给 `node --check`,
还检查注释行里有没有裸控制字符。
为什么原来查不出来:已有的「管理页 JS 合法性」阶段只检查
token 在不在,不查语法 —— 「23 项测试通过」和「功能能用」
是两件事。
2. `_build/scan_admin_escapes.py`
扫源文件里"注释下一行不像 JS 代码"的可疑断行。
3. `_tests/test_admin_live.py`
在**真实中转**上走 HTTP 实测两个新功能(不能进回归套件,
因为它依赖线上设备):
一、管理页能打开(带 X-Admin 头绕开登录页)
二、页面里真的有 allowNew 和改码按钮
三、内嵌 JS 语法合法
四、关掉接入开关 -> 新设备被拒 -> 打开 -> 能注册(实测通过)
五、改配对码 -> 真的变了(实测通过)
六、不带 X-Admin 访问管理接口返回 401(实测通过)
实测结果:16/17 通过(唯一的失败就是上面那个 JS bug,
已修,本地渲染 6/6 通过)。
== 顺带纠正一个我自己的误解 ==
我一开始只带 `?key=` 访问管理页,拿到的是**登录页**,
还以为是设备上部署了旧版本。实际是管理页改成了
**账号 + 密码登录 + Cookie 会话**(用户要求),
脚本通道用 `X-Admin` 头(见 relay.py 的 _admin_gate)。
== 部署时机 ==
**故意没有立刻部署到设备上** —— 部署要重启中转服务,
会打断 relay-stability 正在跑的隧道配比 A/B 对照。
等对照跑完(约 22:00)再部署并复测。
This commit is contained in:
+11
-6
@@ -366,12 +366,17 @@ if (allowNew) allowNew.onchange = async () => {
|
||||
document.querySelectorAll('button[data-recode]').forEach(b => {
|
||||
b.onclick = async () => {
|
||||
const name = b.dataset.name, old = b.dataset.code;
|
||||
// ⚠ 这里必须是 \\n(反斜杠+n),不能是 \n ——
|
||||
// 本文件是普通三引号字符串,写 \n 会被 Python 变成**真实换行**,
|
||||
// 拼进 JS 就是字符串里的裸换行 -> 整段 <script> 语法错误 ->
|
||||
// 页面上所有按钮(改码/删除/批量删除/全选)全部失效。
|
||||
// 这个坑踩过一次(为此专门建了"管理页 JS 合法性"测试阶段),
|
||||
// 加改码功能时又踩了第二次。
|
||||
// ⚠ 下面 prompt 里的换行,必须写成「反斜杠 + n」两个字符。
|
||||
// 本文件是普通三引号字符串:只写反斜杠 + n,Python 会把它
|
||||
// 变成**真实换行**,拼进 JS 就是字符串里的裸换行 ->
|
||||
// 整段 <script> 语法错误 -> 页面上所有按钮(改码/删除/
|
||||
// 批量删除/全选)全部失效。
|
||||
//
|
||||
// 这个坑踩过两次:
|
||||
// 1) 第一次是 prompt 里的换行本身;
|
||||
// 2) 第二次就是**这段注释自己** —— 为了举例说明「不能那样写」,
|
||||
// 注释里原样敲了那个转义,结果注释被断成两行,把整段
|
||||
// JS 又弄坏了一次。所以这里一个转义序列都不写。
|
||||
const typed = prompt('把「' + name + '」的配对码 ' + old
|
||||
+ ' 改成:\\n\\n(必须是 6 位数字)', '');
|
||||
if (typed === null) return;
|
||||
|
||||
Reference in New Issue
Block a user