WPStow WP Registry grade A. No security issues foundWP RegistryNo security issues foundOpen the reportA
WordPress 云端媒体存储插件,支持按图片、视频、音频和其他文件分别路由到 OneImg、S3/R2、WebDAV 或 FTP。
Install
Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/hicocos/wpstow/releases/download/v2.0.5/wpstow-v2.0.5.zip
让 WordPress 媒体库继续按原来的方式工作,把文件存到更合适的地方。
安装 · 开始配置 · 存储服务 · 版本发布 · 问题反馈
WPStow 能做什么
WPStow 把图片、视频、音频和其他附件分别路由到 OneImg、聚合图床、S3、Cloudflare R2、WebDAV 或 FTP。文章编辑、媒体选择、缩略图和 srcset 仍沿用 WordPress 原生流程,不需要改变日常使用习惯。
分类存储
图片可以走图床,视频放 R2,音频放 S3,其他附件留在本地。每类媒体都能单独设置。
大文件直传
S3/R2 支持浏览器预签名直传。大文件自动采用 Multipart 分片和并发上传,失败时回退到 WordPress 服务器流式上传。
私有桶访问
R2 私有桶不必公开。WPStow 使用固定媒体地址完成权限解析,再以 302 跳转到短期预签名 URL,文件内容不经过 PHP。
旧媒体接管
扫描现有媒体库后,可按文件类型批量迁移。任务保存在数据库中,刷新或关闭后台页面后仍能继续执行。
图片处理
支持外链图片本地化、WebP 转换、文字或图片水印,以及不生成缩略图和自动格式副本的原图单文件模式。
失败保护
远端上传没有完整成功时,WPStow 不会删除本地原件。云端删除失败会进入持久队列,由 WP-Cron 继续重试。
工作方式
flowchart LR
A[WordPress 上传] --> B{媒体类型}
B -->|图片| C[OneImg / 聚合图床]
B -->|图片、视频、音频、其他| D[S3 / Cloudflare R2]
B -->|图片、视频、音频、其他| E[WebDAV / FTP]
B -->|任意类型| F[仅保留本地]
D --> G{是否满足直传条件}
G -->|是| H[浏览器预签名直传]
G -->|否或直传失败| I[WordPress 流式上传]
C --> J[记录附件实际存储归属]
H --> J
I --> J
E --> J
附件上传完成后会记录实际使用的存储服务。之后即使切换后台配置,已有附件的 URL、读取和删除仍按各自记录处理。
支持的存储服务
| 存储服务 | 图片 | 视频/音频/其他 | 浏览器直传 | 私有访问 |
|---|---|---|---|---|
| 聚合图床(Superbed) | ✅ | — | — | 由服务商决定 |
| OneImg API | ✅ | — | — | 由服务商决定 |
| S3 兼容存储 | ✅ | ✅ | ✅ | 预签名 URL |
| Cloudflare R2 | ✅ | ✅ | ✅ | 预签名 302 |
| WebDAV | ✅ | ✅ | — | WordPress 代理 |
| FTP/FTPS | ✅ | ✅ | — | WordPress 代理 |
| 本地媒体库 | ✅ | ✅ | — | 由 WordPress 控制 |
安装
从 GitHub Release 安装
- 下载最新稳定版 ZIP。
- 在 WordPress 后台进入“插件 → 安装插件 → 上传插件”。
- 上传 ZIP 并启用 WPStow。
- 打开“WPStow 设置”。
也可以把插件目录上传到 wp-content/plugins/wpstow/,再从后台启用。
[!NOTE] 环境要求:WordPress 6.0 或更高版本、PHP 7.4 或更高版本,以及 PHP cURL 与 JSON 扩展。FTP/FTPS 还需要 PHP FTP 扩展;建议启用 Fileinfo。
开始配置
- 在“存储配置”中为图片、视频、音频和其他附件选择存储服务。
- 切换到对应服务,填写连接参数并执行“测试连接”。
- 选择保留本地副本,或在远端上传成功后删除本地文件。
- 启用“自动转存新上传”并保存。
- 上传一个测试文件,检查媒体地址和远端对象。
“当前配置服务”只控制后台正在编辑哪组连接参数,不会改写已经保存的分类路由。
S3 与 Cloudflare R2
S3 和 R2 使用独立配置。Endpoint 填写 S3 API 地址,不要附加 Bucket 名称;R2 的 Region 使用 auto。
WPStow 在以下条件同时成立时启用浏览器直传:
- 存储服务为 S3 或 Cloudflare R2;
- 本地副本设置为“上传后删除”;
- 文件不需要服务器生成缩略图、转换 WebP 或添加水印。
Bucket CORS 需要允许 WordPress 站点来源执行 PUT,并在 ExposeHeaders 中加入 ETag。不满足条件或直传失败时,插件会把原文件交回 WordPress,改用服务器流式上传。
R2 私有桶可将“公开访问 URL”留空。媒体请求先到 WPStow 的固定解析地址,再跳转到短期预签名 URL;R2 直接向浏览器返回文件。
媒体库接管
“媒体接管”会扫描已有附件,并显示已接管、可接管、失败、处理中、仅本地和源文件缺失等状态。批量任务使用数据库持久队列,支持暂停、继续和取消。
任务按附件串行处理,并对临时故障自动退避重试。只有主文件和必需的衍生文件全部上传成功后,插件才会提交云端状态,并按设置处理本地副本。
安全边界
- 后台设置和操作均检查权限与 nonce。
- HTTPS 请求验证 TLS 证书和主机名。
- 日志不记录密码、Secret Key、API Token、Authorization 或请求签名。
- 上传未完整成功时保留本地原件。
- 云端删除失败后进入持久重试队列。
- S3/R2 凭据应遵循最小权限原则,只授权目标 Bucket 所需操作。
生产环境仍应定期备份 WordPress 数据库和媒体文件,并轮换云存储凭据。
常见问题
配置完成后,媒体为什么仍保存在本地?“测试连接”只确认凭据可用。还需要把“自动转存新上传”设置为启用。是否删除本地副本由单独的本地副本选项决定。 上传失败会删除本地文件吗?
不会。主文件或任一必需衍生文件上传失败时,本地文件都会保留,并记录可重试的错误。 为什么 R2 私有媒体地址包含 admin-ajax.php?
这是固定的链接解析入口。WPStow 校验附件和对象的对应关系后返回 `302`,浏览器随后直接从 R2 获取文件。 S3 对象路径如何组成?
默认沿用 WordPress 年月目录,例如 `2026/08/example.jpg`。这是对象 Key,不是服务器上的真实文件夹。
开发与发布
find . -type f -name '*.php' -print0 | xargs -0 -n1 php -l
for file in static/*.js; do node --check "$file"; done
CI 会在 PHP 7.4、8.1、8.3 上检查语法,并验证前端 JavaScript。推送符合 v* 格式的 Git 标签后,GitHub Actions 会构建可安装 ZIP 并创建 Release。
贡献代码前请阅读 CONTRIBUTING.md。
项目数据
许可证
WPStow 自有代码按 MIT License 发布。内置 Codestar Framework 使用其目录中声明的许可证。
由 梅零落 开发与维护
Releases
8 releases. Each count is every asset in that release; expand a row for the breakdown.