在 iOS Safari 里,<a download> 并不好用——图片会掉进「文件」App。本页演示两种真正能存进「照片」的姿势。
Web Share API 把图片以「文件」分享出去,iOS 系统面板里选择「存储图像」即存入照片 App。
从「照片」里选一张图,浏览器读取后原样存回相册——验证图片在网页与相册之间自由流转。
还没选择照片
最原始也最可靠:直接长按图片,在弹出的菜单里选「存储图像」。任何 iOS 版本都适用。
iOS Safari 对「下载并保存」做了不同的产品决策。
Safari 不会像桌面浏览器那样弹「另存为」,图片要么新开标签页展示,要么被塞进「文件」App 的「下载」目录——反正不进相册。
把图片放进「照片」是系统级操作,网页只能通过 Web Share API(带文件) 或 长按手势菜单 这两个官方通道触达。
Web Share API 只在安全上下文(HTTPS / localhost)里可用。HTTP 站点下按钮会直接失效——本 demo 需要 SSL 证书。
按你实际的使用场景选。
| 方式 | 实现 | iOS 支持 | 落地效果 | 适用 |
|---|---|---|---|---|
| 一键存相册 | navigator.share({files}) |
iOS 15.0+ | 分享面板 → 存储图像 → 照片 | 网页有「保存」按钮 |
| 长按保存 | 系统手势菜单 | 全部版本 | 长按 → 存储图像 → 照片 | 图片直接展示在页面 |
| <a download> | 原生下载属性 | 不支持存相册 | 掉进「文件」App | 只在桌面端可靠 |
| 新标签页打开 | window.open(url) |
可用但繁琐 | 打开后仍需长按一次 | Web Share 不可用时兜底 |
就这几行,是「存进相册」的关键。
// 1. 把图片变成 Blob(同源图片,避免 CORS)
canvas.toBlob(async (blob) => {
// 2. 包装成 File
const file = new File([blob], 'photo.jpg', { type: 'image/jpeg' });
// 3. 先探测:当前设备能不能分享文件?
if (!navigator.canShare || !navigator.canShare({ files: [file] })) {
fallback(); // 不支持 → 提示长按保存
return;
}
// 4. 唤起系统分享面板,选「存储图像」即进相册
await navigator.share({
files: [file],
title: '保存图片',
text: '来自 photo-upload-demo.xsharp.cc',
});
}, 'image/jpeg', 0.95);