[BUG] 在包含跨域 iframe 的复杂网页(如 Reddit)上,Popup 弹窗中的翻译接口/规则自动回退为全局默认设置
- Environment / 运行环境
- OS / 操作系统: [Windows 10]
- Browser / 浏览器: [Chrome 153]
- Software Type / 软件类型: [Extension / 扩展]
- Version / 版本号: [v2.0.32]
- Script Manager / 脚本管理器: [None / 无]
Description / 问题描述 在为部分的特定复杂网站(目前在 Reddit
https://www.reddit.com上稳定复现)配置了专属规则(例如指定翻译服务为某个大模型或专属 API)后: 1 初次打开 Reddit 并通过 Popup 浮窗查看时规则生效; 2 但在页面浏览过程中、或重新点击浏览器右上角的扩展图标打开 Popup 浮窗时,弹窗内的翻译接口会自动回退为全局规则中设定的默认接口(如全局默认的全局模型),导致站点自定义规则被冲掉或回退。 3 即使页面正文实际仍处于翻译状态,Popup 中的显示也会脱节为全局默认状态,若用户在 Popup 中再次操作可能导致意外覆盖站点配置。Steps to Reproduce / 复现步骤 1 将【全局规则】的默认翻译接口设为接口 A ,并在个人规则为reddit.com指定使用专门的接口B 2 打开
https://www.reddit.com,首次点击打开扩展 Popup 浮窗,可以看到个人规则正常生效,使用的是接口B 3 刷新 Reddit 页面或在页面中稍作滚动。 4 再次点击扩展图标呼出 Popup 弹窗。 5 观察 Popup 界面中的接口选择框:稳定回退显示为全局默认的接口 A。Screenshots / 截图 (Optional / 可选)
- 首次打开网站:
- 滚动浏览或者刷新之后再次呼出弹窗:
5.一些可能的原因分析(仅供参考): 导致该问题的原因可能在于 “多 Frame 全量注入” 与 “Popup 降级广播抢答” 构成的竞态条件: 多 Frame 全量注入:
- 扩展在
manifest.json中配置了"all_frames": true,所有嵌套的 iframe 均会注入 Content Script。 - 页面中的第三方/子 iframe 的内部 URL 匹配规则时必然匹配到
GLOBLA_RULE(全局规则)。
顶层通信轻微时延:
- 顶层窗口 DOM 结构庞大且有复杂的 React 渲染逻辑,在刚切回页面或主线程稍忙时,顶层 Frame(
frameId: 0)对 PopupMSG_TRANS_GETRULE消息的响应偶尔会出现几十毫秒的延迟。
子 Frame 抢答污染:
- 在
src/views/Popup/loadData.js中,当顶层 Frame 未能立刻回包时,会触发向当前 Tab 广播的 Fallback 降级机制。 - 轻量级的 iframe 率先响应,返回了属于它自己的
GLOBLA_RULE。 - Popup 接收到该回包后未对来源进行顶层域名鉴权,直接信任了该规则并刷新了 Popup 界面,导致界面状态被篡改为全局规则。
6.一些可能的思路(仅供参考): 明确标识来源 Frame 属性:
- 在
src/libs/translatorManager.js的#handleBrowserMessage响应数据中增加isIframe: this.#isIframe,使 Popup 能够明确知晓当前回包来自顶层窗口还是嵌套子 iframe。
Popup 降级回包鉴权与纠偏:
- 在
src/views/Popup/loadData.js的resolvePopupData处理广播降级回包时:- 通过
getCurTab()获取当前 Tab 的真实顶层 URL。 - 若顶层页面不在黑名单中,且真实 URL 能匹配到站点专属规则,但收到的回包来自于子 iframe 或返回了通配符
GLOBAL_KEY(*),则丢弃子 iframe 的全局规则,基于顶层真实 URL 重新解析出正确的规则(同时保留已同步的transOpen运行态开关)。 - 若顶层页面确实在黑名单中,则继续信任子 frame 规则,以兼顾“受限网页支持翻译局部 iframe”的原生设计。
- 通过
Source: fishjar/kiss-translator