埋点返回 success:true,任务却没计数:一次跨子域会话的排查

举报
yd_293451429 发表于 2026/10/28 10:47:54 2026/10/28
【摘要】 现象 有个「每日体验 AI DevSpace」的任务,点一下按钮就触发埋点上报,任务转完成、+30 分。脚本化之后跑了几天都正常,今天突然不计数了。 日志长这样: POST https://hands-on-agent.developer.huaweicloud.com/api/track/aishell_click HTTP 200 {"success":true} 接口返回成功,任务状态...

现象

有个「每日体验 AI DevSpace」的任务,点一下按钮就触发埋点上报,任务转完成、+30 分。脚本化之后跑了几天都正常,今天突然不计数了。

日志长这样:


POST https://hands-on-agent.developer.huaweicloud.com/api/track/aishell_click
HTTP 200
{"success":true}

接口返回成功,任务状态却是未完成。服务端明确说了 success,但业务上什么都没发生。

第一反应是错的

看到 success:true 很容易往这几个方向想:

• 是不是今天已经做过了(幂等跳过)?→ 查了,没有

• 是不是积分结算延迟?→ 等了 3 分钟,还是没有

• 是不是接口改了、埋点字段变了?→ 抓包对比,请求体和以前一模一样

三条都排除了。问题不在请求本身。

真正的线索:一个被我忽略的接口

回头看这次会话里所有请求,发现页面加载时还调了一个东西:


GET https://hands-on-agent.developer.huaweicloud.com/api/islogin?callback=checklogin
→ checklogin({"flag":0})

flag:0 —— 这个子域认为我没登录。

对比正常情况下的返回:


checklogin({"userId":"01a1477342cb7aafbd80c5f92c1e8a09",
            "username":"hw036720952",
            "domainId":"01a1477342cb7aafbd80c5f92c1e8a09", ...})

有 userId、有 username,是完全不同的结构。

为什么会这样

主域 devdata.huaweicloud.com 的登录态是正常的——我拿 csrf、查积分、发博客全都通。但埋点走的是 hands-on-agent.developer.huaweicloud.com,另一个子域。

关键在这里:会话建立需要一个"落地"动作。主域那套是靠访问业务页(developer.huaweicloud.com/grow)让 cookie 落全,子域同理。如果直接拿主域的会话去打子域接口,子域自己那套 cookie 还没建立,islogin 就返回 flag:0。

于是整条链路变成:


埋点请求发出 → 服务端收到 → 查不到是谁发的 → 记一条匿名事件 → 返回 {"success":true}

接口没撒谎,它确实成功接收并存储了这次点击。只是这条记录没有关联到任何账号,自然不可能触发任务计数。

这是典型的"技术成功 ≠ 业务成功":HTTP 200 和业务码都正常,但语义上这次调用是无效的。

修法

在打开子域之前,先把主域会话激活一次:


b.refresh_csrf()          # 内部会访问 grow 页,建立业务会话
p.goto("https://hands-on-agent.developer.huaweicloud.com/#tasks")

然后再验证子域登录态,确认 flag=1 才继续:


r = ctx.request.get(HOA + "/api/islogin?callback=checklogin")
if "userId" not in r.text():
    log("⚠️ 子域未登录,埋点会匿名上报,先别点")

改完重跑:


子域 islogin: flag=1? True | 含 userId? True
点击 a[data-task=devspace] …
  200 POST /api/track/aishell_click  →  {"success":true}
第1次(20秒): DevSpace 完成=True 积分=550

20 秒后任务转完成,+30 到账。

一个附带的坑:同一个页面的"未绑定"也是假的

排查过程中还撞见一个更隐蔽的。页面上有个「绑定 GitCode 账号」区块,我第一次抓 DOM 时看到的是:


#unboundView  display=block  w=545 h=58     ← 未绑定视图可见
#unbindBtn    w=0 h=0                       ← 解绑按钮尺寸 0
input value = ""                            ← 用户名输入框空的

三个信号一致指向"没绑定过"。于是我怀疑是绑定关系丢了,准备去重建绑定。

但按上面的方法先激活会话再看,同一个页面变成:


#unboundView  display=none  w=0 h=0
#boundView    display=block w=545 h=96
已绑定 GitCode 账号:gcw_8kuR9mW1
关联华为云账号:hw036720952
bound_at: 2026-10-20 02:00:57

早就绑好了,绑了 8 天。 之前看到的"未绑定"是因为页面在 flag:0 状态下渲染,拿不到用户信息,就默认显示了未绑定分支。

如果我当时照着这个 DOM 去调 /api/binding/create 重建绑定,就会把一个正常状态改成未知状态——UI 状态也是会话的函数,不能当独立事实来读。

排查清单

以后再遇到"接口成功但业务没生效",按这个顺序:

1. 别只看目标接口的返回值,把这次会话里所有请求都列出来,找有没有别的接口在报异常状态

2. 特别留意 islogin / whoami / userinfo 这类身份接口,它们的返回结构变了(flag:0 vs 完整用户对象)就是信号

3. 跨子域调用前,先确认目标子域自己的会话建立了,主域登录不等于子域登录

4. DOM 状态要和身份接口交叉验证,页面在匿名态下渲染出来的东西不可信

5. 写操作前先回读状态;写操作后也回读——success:true 只证明请求被接收,不证明业务生效

第 5 条是这个仓库里反复踩的老坑了:code=0、errno=0、success:true 都不等于业务成功,必须回读状态或看余额差值。这次的特殊之处在于,连"回读业务状态"都可能读到假象(那个未绑定视图),所以回读也要在正确的会话状态下做。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。