产品 — FluxFiles
现代文件管理器所需的一切
为需要灵活性的开发者而构建。
多存储
本地、AWS S3、Cloudflare R2, SFTP 通过 Flysystem v3 — 仅改配置即可切换。
嵌入任何地方
iframe + postMessage SDK。独立 UI 使用 Alpine.js(零构建)。适用于任何框架。
JWT认证 + 权限范围
每用户路径前缀、权限声明、磁盘白名单、仅所有者模式——也可从 viewer/editor/admin 角色预设开始。
ACL 角色预设
从 viewer/editor/admin/superadmin 预设中签发令牌——一个参数即可展开正确的权限、磁盘和作用域声明,无需手动拼装。
AI自动标签
Claude / OpenAI vision — 自动alt文本、标题、标签。
图片裁剪
内置裁剪工具,预设宽高比。
图片优化
自动WebP变体 — 缩略图、中等、大图。
预签名上传
浏览器直接上传到S3/R2 — 服务器零带宽消耗。
分片上传
S3 multipart,支持>10MB文件。
全文搜索
对文件名、标题、标签建立索引搜索——默认基于文件,也可选用自己的 SQL 数据库作为后端。
数据库支持的元数据
可选的 FLUXFILES_STORAGE_BACKEND=db 模式——元数据、搜索/文件夹索引和审计日志存储在你自己的 MySQL/PostgreSQL/SQLite 中,而非 JSON 附属文件。无论哪种方式,文件字节都保留在存储端。
批量操作
多选移动、复制、删除、下载。
跨磁盘传输
在本地 ↔ S3 ↔ R2之间复制/移动。
回收站
可恢复删除,自动清理。
SEO元数据
标题、alt、说明、标签 — 云端为 S3 对象元数据,本地为 sidecar JSON。全文搜索。
深色模式
UI 与 SDK 支持浅色 / 深色 / 自动。
16种语言
默认英语。通过 SDK、URL (?locale=) 或 FLUXFILES_LOCALE 设置语言。阿拉伯语 RTL。
审计日志
记录所有写入操作。
速率限制
每用户令牌桶API保护。
存储配额
通过JWT claims设置每用户限制。
BYOB 存储桶
用户自带 S3/R2 — 凭证在 JWT 中加密(AES-256-GCM)。
重复检测
SHA-256 相同则跳过重复上传,除非强制覆盖。
SDK 令牌刷新
401 时 onTokenRefresh — 合并刷新、重试,以及 updateToken() 主动轮换。
存储桶体检
诊断任意 S3/R2 磁盘——凭证、读/写/删、预签名、CORS、分片——并给出可直接粘贴的 IAM 与 CORS 修复方案。几分钟接入 BYOB 存储桶。
SFTP 磁盘
继 S3/R2 之后的第三种驱动——把任意 VPS 或共享主机变成文件管理器。
代码 / 配置编辑器
在浏览器中编辑文本与配置文件(wp-config.php、.env、nginx.conf),类 cPanel。
压缩与解压
将选中项打包为 zip,或就地解压——已防 zip-slip 与压缩炸弹。
水印
实时叠加文字或 Logo 水印以保护预览——绝不修改原文件。
按需 WebP + AVIF
通过一个 URL 以缓存的 AVIF/WebP 提供任意尺寸图片(按 Accept 协商),附带响应式 srcset。
SFTP 权限
用类 cPanel 对话框更改 SFTP 磁盘上的 Unix 文件权限(chmod)。
SSH 终端
SFTP 磁盘上的无状态命令行终端——类 cPanel 的管理工具,内置且免费(也可嵌入自建的 ttyd 获得完整 PTY)。
一键 Git 部署
直接从文件管理器在 SFTP 服务器上拉取并重置 Git 仓库——固定形式,非任意 shell,默认关闭 hooks。
用量面板
一目了然的存储用量——配额加按类型和文件夹的细分。
媒体预览
内联预览图片、视频、音频与 PDF;私有本地媒体安全流式传输(支持 Range)。
2分钟启动运行
composer require fluxfiles/fluxfiles
cp .env.example .env
# .env
FLUXFILES_SECRET=your-random-32-char-secret
FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com
require_once 'vendor/autoload.php';
$token = fluxfiles_token(
userId: 'user-123',
perms: ['read', 'write', 'delete'],
disks: ['local', 's3', 'r2'],
prefix: 'user-123/',
maxUploadMb: 10,
allowedExt: null,
ttl: 3600
); composer require fluxfiles/laravel
php artisan vendor:publish --tag=fluxfiles-config
# .env — point the adapter at your FluxFiles server
FLUXFILES_ENDPOINT=https://fm.yourdomain.com
FLUXFILES_SECRET=your-secret-min-32-chars
# Optional: match CORS on the FluxFiles host
# FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com
# Config: config/fluxfiles.php npm install @fluxfiles/node
// Express / Next.js route — mint a token from your JS backend (no PHP)
import { createToken } from '@fluxfiles/node';
app.get('/fluxfiles-token', (req, res) => {
const token = createToken({
secret: process.env.FLUXFILES_SECRET, // >= 32 bytes
userId: req.user.id,
perms: ['read', 'write', 'delete'],
prefix: `users/${req.user.id}`,
ttl: 3600,
});
res.json({ token });
}); pip install fluxfiles-token
# FastAPI / Django / Flask route — mint a token from your Python backend (no PHP)
from fluxfiles_token import create_token
@app.get("/fluxfiles-token")
def fluxfiles_token(user=Depends(current_user)):
token = create_token(
secret=os.environ["FLUXFILES_SECRET"], # >= 32 bytes
user_id=user.id,
perms=["read", "write", "delete"],
prefix=f"users/{user.id}",
ttl=3600,
)
return {"token": token} <!-- Demo: unpkg. In production, serve fluxfiles.js from your FluxFiles host -->
<script src="https://unpkg.com/fluxfiles@latest/fluxfiles.js"></script>
<script>
FluxFiles.open({
endpoint: 'https://your-api.com',
token: 'eyJhbGci...',
disk: 'local',
mode: 'picker',
container: '#file-picker',
onSelect: function(file) {
console.log('Selected:', file.url);
},
async onTokenRefresh() {
const r = await fetch('/api/auth/refresh-fluxfiles-token');
const { token } = await r.json();
return token;
}
});
</script> npm install @fluxfiles/react
import { FluxFilesModal } from '@fluxfiles/react';
<FluxFilesModal
open={open}
endpoint="https://your-api.com"
token={token}
onSelect={(file) => console.log(file)}
onClose={() => setOpen(false)}
/> npm install @fluxfiles/vue
<script setup>
import { FluxFilesModal } from '@fluxfiles/vue';
</script>
<FluxFilesModal
v-model:open="open"
endpoint="https://your-api.com"
:token="token"
@select="onSelect"
@close="open = false"
/> git clone https://github.com/thai-pc/fluxfiles.git
docker build -f fluxfiles/docker/Dockerfile.prod -t fluxfiles fluxfiles
docker run -p 8080:80 \\
-e FLUXFILES_SECRET=your-random-32-char-secret \\
fluxfiles
# UI: http://localhost:8080/public/index.html git clone https://github.com/thai-pc/fluxfiles.git
cd fluxfiles
composer install -d packages/core
cp .env.example .env
cd packages/core
php -S localhost:8080 router.php
# UI: http://localhost:8080/public/index.html
# API: http://localhost:8080/api/fm/list?disk=local&path= 兼容
集成
适配你技术栈的即插即用适配器
官方适配器可将 FluxFiles 原生嵌入你已经在用的框架和编辑器中。
嵌入
几行代码即可嵌入
加载 fluxfiles.js,传入由服务端签发的 JWT,即可把完整的文件管理器(或文件选择弹窗)放进任意页面。
<script src="https://fm.example.com/fluxfiles.js"></script>
FluxFiles.open({
endpoint: 'https://fm.example.com',
token: 'eyJhbGci...', // JWT from your backend
disk: 'local',
mode: 'picker', // select & close
theme: 'auto',
onSelect(file) {
// { url, key, name, size, disk, meta, variants }
document.querySelector("#img").src = file.url;
},
}); <div id="fm" style="height:600px"></div>
FluxFiles.open({
endpoint: 'https://fm.example.com',
token: 'eyJhbGci...',
mode: 'browser', // full manager, stays open
container: '#fm', // omit for a modal overlay
disks: ['local', 's3', 'r2'],
});
FluxFiles.on('FM_EVENT', (e) => console.log(e.event));
FluxFiles.navigate('/photos/2024'); import { FluxFilesModal } from '@fluxfiles/react';
function Picker({ open, setOpen, token }) {
return (
<FluxFilesModal
open={open}
endpoint="https://fm.example.com"
token={token}
onSelect={(file) => console.log(file.url)}
onClose={() => setOpen(false)}
/>
);
} 令牌在服务端签发——切勿把密钥发送到浏览器。
为他人遗忘之处而构建
| 功能 | FluxFiles | elFinder | Laravel-FM | RichFilemanager | Responsive FM |
|---|---|---|---|---|---|
| S3 + R2 + Local + SFTP | ✓ | ⚠ | ⚠ | ⚠ | ✗ |
| 嵌入任何框架 | ✓ | ⚠ | ✗ | ⚠ | ✗ |
| JWT认证 + 权限范围 | ✓ | ✗ | ✗ | ✗ | ✗ |
| SEO元数据 | ✓ | ✗ | ✗ | ✗ | ✗ |
| AI自动标签 | ✓ | ✗ | ✗ | ✗ | ✗ |
| 图片裁剪 | ✓ | ✓ | ✗ | ✗ | ✗ |
| 分片上传 | ✓ | ✗ | ✗ | ✗ | ✗ |
| 全文搜索 | ✓ | ✗ | ✗ | ✗ | ✗ |
| 深色模式 | ✓ | ✗ | ⚠ | ✗ | ✗ |
| 16种语言 | ✓ | ✓ | ✗ | ✗ | ✗ |
| PHP ≥ 8.1 | ✓ | ✓ | ✗ | ✓ | ✓ |
| 积极维护中 | ✓ | ✓ | ⚠ | ✗ | ✗ |
| 现代UI | ✓ | ✗ | ⚠ | ✗ | ✗ |
| 能力 | FluxFiles | Filestack | Uploadcare | Cloudinary | Supabase Storage |
|---|---|---|---|---|---|
| 自托管(运行在你的基础设施) | ✓ | ✗ | ✗ | ✗ | ⚠ |
| BYOB——每个客户自有存储桶 | ✓ | ⚠ | ⚠ | ✗ | ✗ |
| 可嵌入的文件管理器 UI | ✓ | ✓ | ✓ | ⚠ | ✗ |
| 开源(MIT) | ✓ | ✗ | ✗ | ✗ | ✓ |
| 无按存储/上传的 SaaS 费用 | ✓ | ✗ | ✗ | ✗ | ⚠ |
| 多存储(S3 / R2 / 本地) | ✓ | ⚠ | ✗ | ✗ | ✗ |
| 内置按租户令牌作用域 | ✓ | ⚠ | ⚠ | ⚠ | ⚠ |
对比反映各产品的典型默认能力;每款产品在各自领域都很出色。FluxFiles 的定位是可嵌入、自托管、自带存储桶三者的组合。
对比数据截至 September 2026,非官方关联——如需纠正请前往 GitHub 仓库反馈。
常见问题