---
title: "相册顺滑、拍照翻车：我用 AI 当“副驾”揪出 Hybrid 里 SSE 断连和 File 假上传"
date: 2025-06-03
description: "移动端 AI 识图踩过坑：选相册丝滑，点“直接拍照”就 Network Error 搞心态。这篇不装神弄鬼，只写我怎么借 AI 把症状收成一张排查地图，以及上传→排队推理→SSE 刷进度这条链，为啥偏偏跟相机把 WebView 怼进后台掐得死死的。顺手记下 openWhenHidden、file.raw 脱壳，能少熬一晚是一晚。"
canonical_url: "https://yijinlee.com/articles/article-2"
tags:
  - WebView
  - "SSE (Server-Sent Events)"
  - "File API"
  - JavaScript
  - "iOS/Android Hybrid"
  - 图像推理链路
topic: "AI 外骨骼"
---

### 那天我在移动端 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。**

## 参考文章：相关链接

- [MDN · Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File_API/Using_files_from_web_applications)（官方文档）— File / FormData 上传的浏览器契约，对照 Hybrid「假上传」根因。
- [MDN · Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)（权威引文）— SSE 连接生命周期与重连语义，解释相册顺滑但拍照链路断连。
- [Hybrid 实录：iOS 上导航栏高度“玄学”](https://yijinlee.com/articles/article-31)（站内深度）— 同一 Hybrid 容器族的另一类「看起来像前端、其实是桥」问题。
- [统一码 + 上传文件：一张 jpeg 逼我重新认 API 的券码改造复盘](https://yijinlee.com/articles/article-54)（站内深度）— 上传语义与 API 契约再次冲突时的排障范式。

