← 返回文章列表
所属专题:AI 外骨骼

相册顺滑、拍照翻车:我用 AI 当“副驾”揪出 Hybrid 里 SSE 断连和 File 假上传

更新于 2025-10-08年份:2025字数:1,920阅读时长:7 分钟

移动端 AI 识图踩过坑:选相册丝滑,点“直接拍照”就 Network Error 搞心态。这篇不装神弄鬼,只写我怎么借 AI 把症状收成一张排查地图,以及上传→排队推理→SSE 刷进度这条链,为啥偏偏跟相机把 WebView 怼进后台掐得死死的。顺手记下 openWhenHidden、file.raw 脱壳,能少熬一晚是一晚。

TL;DR · 核心结论

  • 1AI 当实习生用:你把现象、时间线、机型表丢过去,它帮你列可证伪的清单;锤子还是得自己抡。
  • 2链路记牢:multipart 上去排队推理,SSE 往下灌进度;后台一 nap,管道可能比 GPU 先凉。
  • 3动手三板斧:openWhenHidden + 重连兜底;上传前 raw 脱壳;“相册 OK、拍照挂” 先查可见性,再查序列化。

那天我在移动端 AI 识图里当电工

相册选图顺得像抹了黄油;一按 “直接拍照”,接口开始随机投喂 `Network Error`、`Abort`,像在抽盲盒。我一度想给 WebView 填工单:请咨询心理健康服务。

双端日志啃久了会上头。后来我把 “只有拍照才炸” 写进备忘录,配上时间线和请求草图,扔给 AI 当副驾驶。它不能替你抓包,但擅长把散装症状钉到几种常见剧本上:Page Visibility、SSE 默认策略、Upload 对 File 的二次包装——等于先画路线图,我负责踩油门验收。省的是瞎 grep 的命,不是思考的命。

这套业务人话版:图 multipart 上去,服务端排队跑视觉模型(吃像素张量,不吃 JSON 里华丽形容词),进度靠 SSE 往下淌。用户眼里是 “边识别边刷条”;所以 SSE 一断,不一定是模型罢工,也可能是管道先咽气——这句我跟产品复述过无数遍,比画时序图省事。


一、案发现场:拍照凭什么比相册狠?

相册路径: 系统相册弹起来,H5 多半还在前台晃,WebView 懒得睡。

拍照路径: 相机全屏占坑,内存紧的机器顺手把 WebView 塞进后台,`document.hidden` 变成 `true`,像被按了静音 nap。

对某些 SSE 实现来说,这一 nap 就是下班铃:hidden 就掐长连接,省流量省得理直气壮。你拍完照回到页面,管子里早凉了,你还在那儿假装上传——社死级别略高。


二、拆开看:连接层和数据层各来一刀

1. 连接层:SSE 跟 Page Visibility 的别扭婚姻

SSE 就是 HTTP 长连接 + 服务端单向吐事件,适合做进度、日志流这种配角戏。不少 polyfill(比如 `event-source-polyfill`)默认带着 “看不见就别折腾” 的家长式关怀——在相机场景里,关怀就是事故现场。

修法不玄学:打开 `openWhenHidden: true`,再用 `visibilitychange` 把重连和状态回补写成肌肉记忆。别幻想一条 SSE 扛全家,该短轮询、该退避重试就上;不然 PM 问 “为啥相册从不翻车”,你只能表演沉默是金。

2. 数据层:File 被组件库过度溺爱

Element Plus、Vant 一类为了预览、列表管理,会给 `File` 穿马甲:Proxy、包装对象应有尽有。你把整坨丢进 `FormData`,序列化一犯懒,服务端收到哲学意义上的 `[object Object]`——壳子在,肉没了,模型只能懵圈。

上传前扒一层:`file.raw` 或 `file.originFileObj`,确认 multipart 里是真 Blob。推理链路再花哨,入口永远是干净的二进制;这里偷一次懒,后面全是 “玄学调试” 陪跑。


三、几条在 Hybrid 里真能救命的土办法

出门前记账: 跳系统相机前,会话 id、任务 id 写下来,回来还能续命,别指望用户替你记。

长连接当电报: SSE/WebSocket 当 “尽量送达” 的通知网;关键结果要有接口或可追溯的存储兜底,断了还能圆回来。

上传流水线强迫症: 看见代理对象就问自己一句——这是原生 Blob 吗?不是?再剥一层皮。


四、收个尾

“相册正常、拍照必挂” 不像都市传说,拆开就是 宿主爱杀后台 + 前端爱包对象 的老双人舞。AI 帮我少在错误方向上通宵,但最后盖章的那几锤,还是手机里一遍遍复现敲出来的。

如果你也在容器里做识图、质检、扫描——愿你的长连接少断、你的 `FormData` 里永远有真肉。晚安请留给睡觉,别留给 silent disconnect。

本文属于 AI 实用主义流派 的第 2 篇肉身实战。

阅读时长:7 分钟


文档信息

版权声明:自由转载-非商用-非衍生-保持署名(CC BY-NC-ND 3.0)

原文链接:https://yijinlee.com/articles/article-2

作者:李奕锦

商业用途或修改衍生请联系授权。


李奕锦
李奕锦

全栈工程师,业余马拉松选手。

TL;DR

  • AI 当实习生用:你把现象、时间线、机型表丢过去,它帮你列可证伪的清单;锤子还是得自己抡。
  • 链路记牢:multipart 上去排队推理,SSE 往下灌进度;后台一 nap,管道可能比 GPU 先凉。
  • 动手三板斧:openWhenHidden + 重连兜底;上传前 raw 脱壳;“相册 OK、拍照挂” 先查可见性,再查序列化。
Tags:WebViewSSE (Server-Sent Events)File APIJavaScriptiOS/Android Hybrid图像推理链路

该专题下的阅读路径

AI Coding架构排障

常见问题 FAQ

Q1. 为什么 H5 拍照上传会失败?
常常是两条线叠着来:相机一开,页面进后台,SSE 被当成省电标兵掐掉,进度条在黑暗里等死。另一条是上传组件给你的是包装过的 “File 概念”,`FormData` 里塞了个寂寞,服务端啃到空壳。相册挑图多半不切后台,所以你眼前是 “一半天堂一半地狱”。
Q2. 如何解决 WebView 进后台 SSE 断连?
给 SSE 客户端开 `openWhenHidden`(或等价开关),别让它在 `hidden` 时自作多情省流量;再靠 `visibilitychange` 做重连和状态回补。识图这种业务,用户盯的是进度条,不是 HTTP 状态码——断了比 500 还搞心态。
Q3. File 上传变 `[object Object]` 怎么办?
组件库爱的是自己的包装,不是你的原生 Blob。上传前揪出 `file.raw` / `originFileObj`,把真·`File` 塞进 `FormData`。模型吃的是字节,不吃对象的自我介绍。

发表评论

分享你的想法和反馈

支持 Markdown 格式

0/5000