Module
WebUI & Remote Access
Platform
macOS (Apple Silicon)
AionUi Version
2.2.1
Bug Description
通过 WebUI 在手机浏览器上远程访问 AionUi 时,会话附件 / 预览面板中的"下载"按钮无法将文件保存到手机。长按复制出的下载链接形如:
http://blob:https//192.168.x.x:port/...
即一个 blob: URL(真实格式为 blob:https://192.168.x.x:port/<uuid>)。blob: URL 只在创建它的那个浏览器标签页会话内有效,因此在手机端点击下载会变成"导航到一个无效的 blob 链接",既不弹出保存,也无法通过复制链接在其他上下文打开。
根因定位(基于当前代码):
packages/desktop/src/renderer/utils/file/download.ts 中 triggerBlobDownload()(L12-21)使用 URL.createObjectURL(blob) 生成下载地址,再用 <a download> 触发点击。桌面浏览器对 <a download> + blob 支持良好,但移动端浏览器(iOS Safari 及各类 in-app webview)对该组合支持不完整,会将点击当作页面导航处理,导致上述现象。
- 所有下载入口都汇入该函数:
downloadFileFromPath()(L27-36):预览面板下载按钮(PreviewPanel.tsx L698)、消息中图片下载(MessageToolGroupSummary.tsx L43、MessageAcpToolCall.tsx L120);
downloadFileFromRef()(L45-51)与 downloadTextContent()(L56-59)。
- 值得注意的是,
downloadFileFromRef() 内部已经通过同源反代 fetch /api/fs/stream(见 fileUrls.ts 的 buildFileStreamUrl(),L11-20),说明设备无关的下载 URL 基础设施已经存在,只是最终被转成了 blob。
Steps to Reproduce
- 桌面端启动 AionUi 并开启 WebUI 远程访问
- 在手机浏览器打开 WebUI 地址,进入一个包含附件(或 AI 生成了文件)的会话
- 打开预览面板,点击"下载"按钮(或点击消息中图片的下载)
- 手机上没有任何保存动作;长按/复制得到的链接为
blob:https//192.168.x.x...,无法打开
Expected Behavior
文件可以正常保存到手机本地,文件名正确。
Actual Behavior
点击下载无反应(或跳转到一个 blob: 链接后失败),附件无法下载到手机。
Additional Context
建议的修复方向:
- 服务端让
/api/fs/stream(或新增 /api/fs/download)在下载场景返回 Content-Disposition: attachment; filename*=UTF-8''<file_name>,这样任何浏览器 / 设备直接导航该 URL 即可保存文件;
- 前端将
downloadFileFromRef() 从"fetch → blob → createObjectURL"改为直接导航 / <a href={streamUrl}> 到 stream URL(可加 &filename= 参数供服务端设置响应头);
downloadFileFromPath() 同样统一走 stream URL,避免 blob 路径。
这样桌面端与移动端可以共用一条设备无关的下载路径,同时规避各移动端浏览器对 <a download> + blob 支持不一致的问题。
Module
WebUI & Remote Access
Platform
macOS (Apple Silicon)
AionUi Version
2.2.1
Bug Description
通过 WebUI 在手机浏览器上远程访问 AionUi 时,会话附件 / 预览面板中的"下载"按钮无法将文件保存到手机。长按复制出的下载链接形如:
即一个
blob:URL(真实格式为blob:https://192.168.x.x:port/<uuid>)。blob:URL 只在创建它的那个浏览器标签页会话内有效,因此在手机端点击下载会变成"导航到一个无效的 blob 链接",既不弹出保存,也无法通过复制链接在其他上下文打开。根因定位(基于当前代码):
packages/desktop/src/renderer/utils/file/download.ts中triggerBlobDownload()(L12-21)使用URL.createObjectURL(blob)生成下载地址,再用<a download>触发点击。桌面浏览器对<a download>+ blob 支持良好,但移动端浏览器(iOS Safari 及各类 in-app webview)对该组合支持不完整,会将点击当作页面导航处理,导致上述现象。downloadFileFromPath()(L27-36):预览面板下载按钮(PreviewPanel.tsxL698)、消息中图片下载(MessageToolGroupSummary.tsxL43、MessageAcpToolCall.tsxL120);downloadFileFromRef()(L45-51)与downloadTextContent()(L56-59)。downloadFileFromRef()内部已经通过同源反代 fetch/api/fs/stream(见fileUrls.ts的buildFileStreamUrl(),L11-20),说明设备无关的下载 URL 基础设施已经存在,只是最终被转成了 blob。Steps to Reproduce
blob:https//192.168.x.x...,无法打开Expected Behavior
文件可以正常保存到手机本地,文件名正确。
Actual Behavior
点击下载无反应(或跳转到一个
blob:链接后失败),附件无法下载到手机。Additional Context
建议的修复方向:
/api/fs/stream(或新增/api/fs/download)在下载场景返回Content-Disposition: attachment; filename*=UTF-8''<file_name>,这样任何浏览器 / 设备直接导航该 URL 即可保存文件;downloadFileFromRef()从"fetch → blob → createObjectURL"改为直接导航 /<a href={streamUrl}>到 stream URL(可加&filename=参数供服务端设置响应头);downloadFileFromPath()同样统一走 stream URL,避免 blob 路径。这样桌面端与移动端可以共用一条设备无关的下载路径,同时规避各移动端浏览器对
<a download>+ blob 支持不一致的问题。