Tiny File Manager 2.6 常用操作详解
Tiny File Manager 2.6 日常操作手册:登录会话/搜索/新建/编辑/备份/重命名/复制移动/删除/打包解压/上传下载/chmod 全操作,Web 入口与 curl 接口双形态并附实测回显(2026-11-01)
Tiny File Manager 2.6 常用操作详解
目标:作为 Tiny File Manager 2.6 的日常操作手册,覆盖登录会话、浏览搜索、新建/编辑/备份/重命名/复制/移动/删除、打包解压、上传下载、权限修改与 Settings 面板全部常用操作——每个操作同时给出 Web 界面入口与 curl 接口形态(含真实请求参数与实测响应回显),读者既可以在浏览器里点,也可以在服务器上用脚本自动化。全部命令与回显于 2026-11-01 在 Ubuntu 22.04 实机实测通过。
一、环境信息
- 应用版本:Tiny File Manager 2.6(官方镜像
tinyfilemanager/tinyfilemanager:master,2026-07-20 构建,PHP 7.4.33) - 运行环境:Ubuntu 22.04(x86_64),Web 端口 8134,文件根目录
/var/www/html/data(挂载宿主data/目录) - 部署与配置:见 《Tiny File Manager Docker Compose 部署指南》与《Tiny File Manager 2.6 配置参数详解》
- 演示账号:
admin / q1w2e3r4(可写管理员)、user / 12345(只读账号) - 应用无独立 REST API:全部操作复用 Web 页面的 GET/POST 表单与 AJAX 端点,均以 CSRF token 校验(下文统一实测)
二、操作概览
Tiny File Manager 的全部操作围绕一个入口 URL 展开:/index.php?p=<子路径>。p 参数是当前所在目录(相对文件根),写操作全部要求携带与会话绑定的 token。操作清单与调用形态:
| 操作域 | Web 界面入口 | 接口形态(实测) | 只读账号 |
|---|---|---|---|
| 登录/登出 | 登录页 / Sign Out | POST fm_usr,fm_pwd,token;GET logout=1 | — |
| 浏览目录 | 目录树点击 | GET ?p=<dir> | ✅ 可用 |
| 搜索 | Advanced Search | POST AJAX type=search | ✅ 可用 |
| 新建目录/文件 | New Item | POST newfile,newfilename,token | ❌ 拒绝 |
| 在线编辑 | 文件行 Edit | GET edit=<f>;POST AJAX type=save | ❌ 拒绝 |
| 备份副本 | 文件行 Backup | POST AJAX type=backup | ❌ 拒绝 |
| 重命名 | 文件行 Rename | POST rename_from,rename_to,token | ❌ 拒绝 |
| 复制/移动 | 文件行 Copy/Move | GET copy=<src>&finish=1[&move=1] | ❌ 拒绝 |
| 删除 | 文件行 Delete / 批量 Delete | GET del=<name> + POST token | ❌ 拒绝 |
| 打包 zip/tar | 批量选择后 Zip/Tar | POST group[],file[],zip/tar,token | ❌ 拒绝 |
| 解压 | 压缩包行 Unzip | POST unzip,token | ❌ 拒绝 |
| 下载 | 文件行 Download | GET dl=<file> + POST token | ✅ 可用 |
| 上传 | Upload | multipart file,fullpath,dzchunkindex,dztotalchunkcount,token;AJAX type=upload+uploadurl | ❌ 拒绝 |
| 权限修改 | Perms 列链接 | POST chmod,ur..ox,token | ❌ 拒绝 |
| Settings | Settings 面板 | POST AJAX type=settings | ❌ 拒绝 |
关键差异解读:只读账号(user)能用的只有浏览、搜索、下载三类;其余操作在界面层不渲染、接口层也被服务端拦截(实测确认)。
三、前置条件:准备一个已登录的 curl 会话
所有接口实测都需要「会话 cookie + CSRF token」两件套。以下三步在服务器上准备(每步均有实测回显):
BASE=http://localhost:8134
# 1) 请求登录页:把会话 cookie 存进 cj.txt,并从页面取出 token
curl -s -c cj.txt $BASE/ -o login.html
TOKEN=$(grep -oE 'name="token" value="[^"]+"' login.html | sed 's/.*value="//;s/"$//')
echo "$TOKEN"
实测回显(token 为 64 位十六进制,每次会话不同):
d10dc2d96d58f302b060ca7cec8053a55795e4a2c86391235fe8321adb40592d
# 2) 表单登录(登录失败时服务端强制延迟 1 秒)
curl -s -b cj.txt -c cj.txt -d "fm_usr=admin&fm_pwd=q1w2e3r4&token=$TOKEN" -L "$BASE/index.php?p=" -o main.html
grep -oE 'You are logged in|Login failed[^<]*' main.html
实测回显:
You are logged in
登录页 token 在登录后仍然有效(token 存于会话,与登录状态无关),下文各操作继续复用 $TOKEN 与 cj.txt。
⚠️ 两个实测踩坑点,直连接口必读:
- 写操作的 POST 地址必须带
?p=。不带时应用会先 302 重定向到?p=,POST 表单数据随重定向丢失、操作静默无效(实测确认);- token 必须放在 POST 表单里(部分端点只认 POST body 的 token,放在 URL 查询串无效,下载接口实测确认)。
登出(实测回显:返回登录表单,含 fm_usr 输入框):
curl -s -b cj.txt -L "$BASE/index.php?p=&logout=1" | grep -oE 'name="fm_usr"'
name="fm_usr"
四、各操作详解
4.1 浏览目录与搜索
浏览目录就是打开 ?p=<子目录>;文件列表在页面表格中(Name/Size/Modified/Perms/Owner/Actions 六列)。搜索用 AJAX 端点,递归扫描当前目录及子目录:
# 搜索文件名包含 welcome 的条目(path=. 表示从根开始)
curl -s -b cj.txt -d "ajax=1&type=search&path=.&content=welcome&token=$TOKEN" "$BASE/index.php?p="
实测回显:
[{"name":"welcome.md","type":"file","path":""},{"name":"welcome.md_261101_145928.tar","type":"file","path":""},{"name":"welcome.md-01Nov26-145736.bak","type":"file","path":""}]
返回 JSON 数组:name 文件名、type file/folder、path 相对根的目录。Web 界面右上角 Advanced Search 弹窗即调用此端点。
4.2 新建目录与文件
Web 界面顶部 New Item,选 File 或 Folder 并填名称。接口形态(newfile 取值 folder 或 file):
# 新建目录 projects
curl -s -b cj.txt -d "newfile=folder&newfilename=projects&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE '(Folder|File) <b>[^<]+</b> [A-Za-z ]+'
# 新建文件 notes.md
curl -s -b cj.txt -d "newfile=file&newfilename=notes.md&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE '(Folder|File) <b>[^<]+</b> [A-Za-z ]+'
实测回显:
Folder <b>projects</b> Created
File <b>notes.md</b> Created
创建结果落在 $root_path 指向的文件根(挂载卷),宿主侧 ls ./data/ 立即可见同名目录/文件。重名时提示 already exists,含 ../ 等穿越字符的名称被拒绝。
4.3 在线编辑与保存
Web 界面点击文件的 Edit 进入 ace.js 编辑器,Ctrl+S 保存。接口形态——edit=<文件名> 放 URL,新内容放 POST 的 content,保存成功返回 1:
curl -s -b cj.txt --data-urlencode "ajax=1" --data-urlencode "type=save" \
--data-urlencode "content=hello tiny file manager
line2 测试中文" \
--data "token=$TOKEN" "$BASE/index.php?p=&edit=welcome.md" -w ' [%{http_code}]'
实测回显(保存成功,HTTP 200):
1 [200]
落盘验证(文件内容与提交一致,注意末尾无换行):
hello tiny file manager
line2 测试中文
查看(不编辑)用 ?p=&view=<文件名>,页面标题实测变为 Tiny File Manager | welcome.md;只读查看页用 highlight.js 做语法高亮。
4.4 备份副本
编辑器页面的 Backup 按钮触发。接口在当前目录生成 <文件名>-<日Mon年-时分秒>.bak 副本:
curl -s -b cj.txt -d "ajax=1&type=backup&file=welcome.md&p=&token=$TOKEN" "$BASE/index.php?p="
实测回显:
Backup welcome.md-01Nov26-145736.bak created
宿主侧确认:
welcome.md
welcome.md-01Nov26-145736.bak
💡 说明:备份副本是「改配置文件前先留后路」的最快手段——时间戳后缀天然防覆盖,配合
$exclude_items = array('*.bak')可以让列表不显示这些备份。
4.5 重命名与复制/移动
重命名(POST rename_from/rename_to,同目录内改名):
curl -s -b cj.txt -d "rename_from=welcome.md&rename_to=hello.md&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE 'Renamed from <b>[^<]+</b> to <b>[^<]+</b>'
实测回显:
Renamed from <b>welcome.md</b> to <b>hello.md</b>
复制/移动到当前目录用 copy=<源>&finish=1(源可以是子目录里的路径),加 move=1 即为移动(实测移动成功时页面提示 Moved from <b>projects/welcome.md</b> to <b>welcome.md</b>):
# 复制根目录 welcome.md 到 projects/
curl -s -b cj.txt -L "$BASE/index.php?p=projects©=welcome.md&finish=1&token=$TOKEN" | grep -oE 'Copied[^<]*(<b>[^<]+</b>[^<]*)*'
# 移动 projects/welcome.md 回根目录
curl -s -b cj.txt -L "$BASE/index.php?p=©=projects/welcome.md&move=1&finish=1&token=$TOKEN" | grep -oE 'Moved from[^<]*(<b>[^<]+</b>[^<]*)*'
实测回显:
Copied from <b>welcome.md</b> to <b>projects/welcome.md</b>
Moved from <b>projects/welcome.md</b> to <b>welcome.md</b>
⚠️ 注意:目标是「当前
p目录」而不是任意指定目录,跨目录操作先切到目标目录再给源路径。目标已存在同名文件时移动/复制失败,页面提示File or folder with this path already exists(实测复现:目标同名时不产生第二条副本)。
4.6 删除
单个删除用 del=<名称> + POST token(实测回显 File <b>hello.md</b> Deleted):
curl -s -b cj.txt -L "$BASE/index.php?p=&del=hello.md" --data "token=$TOKEN" | grep -oE '(File|Folder) <b>[^<]+</b> (Deleted|not deleted)'
File <b>hello.md</b> Deleted
批量删除:列表勾选多个条目后点 Delete(表单为 group[]=<名称> 数组 + delete + token)。删除是物理删除,没有回收站——批量操作前建议先用 4.4 的备份或先打包归档。
4.7 打包 zip/tar 与解压
批量打包:POST group[] 触发打包动作,file[] 列出要打包的条目,zip= 或 tar= 二选一:
# 多选打包 zip(自动命名 archive_年月日_时分秒.zip)
curl -s -b cj.txt -d "group[]=1&file[]=welcome.md&file[]=welcome.md-01Nov26-145736.bak&zip=&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE 'Archive <b>[^<]+</b> Created'
# 单选打包 tar(命名 <文件名>_年月日_时分秒.tar)
curl -s -b cj.txt -d "group[]=1&file[]=welcome.md&tar=&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE 'Archive <b>[^<]+</b> Created'
实测回显:
Archive <b>archive_261101_145928.zip</b> Created
Archive <b>welcome.md_261101_145928.tar</b> Created
解压用 POST unzip=<压缩包>,加 tofolder=1 则解压到以包名命名的新目录:
curl -s -b cj.txt -d "unzip=up.zip&tofolder=1&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE 'Archive unpacked|not unpacked'
实测回显(宿主侧 up/ 目录出现且内容与包内一致):
Archive unpacked
⚠️ 打包/解压依赖 PHP 的 ZipArchive(zip)与 PharData(tar)扩展——官方镜像已内置 zip 扩展,自建 PHP 环境需自行安装,否则提示
Operations with archives are not available。
4.8 下载
单文件下载是「GET dl=<文件名> + POST token」的组合(实测:只把 token 放 URL 会返回页面而非文件):
curl -s -b cj.txt -d "token=$TOKEN" "$BASE/index.php?p=&dl=welcome.md"
实测回显(文件原始内容):
hello tiny file manager
line2 测试中文
浏览器端点文件行的 Download 即等价操作。批量下载可先 4.7 打包再下载压缩包。
4.9 上传:本地 multipart 与远程 URL
本地文件上传(multipart 表单,fullpath 必填为目标文件名,分片字段固定传 0/1):
curl -s -b cj.txt \
-F "file=@./archive_261101_145928.zip;filename=up.zip" \
-F "p=" -F "dzchunkindex=0" -F "dztotalchunkcount=1" \
-F "fullpath=up.zip" -F "token=$TOKEN" "$BASE/index.php?p="
实测回显:
{"status":"success","info":"file upload successful"}
⚠️ 排障实录:
fullpath留空时,落盘文件名会变成_261101150003.zip这类「下划线+时间戳」(应用以空文件名拼时间戳命名)——浏览器端由 dropzone 自动带上fullpath,直连接口必须手工传。实测确认带上fullpath=up.zip后文件名正确。
远程 URL 拉取(服务器主动从 URL 下载并落盘,Web 界面 Upload 弹窗的 URL 标签页即此功能):
curl -s -b cj.txt -d "ajax=1&type=upload&uploadurl=https://example.com/file.zip&token=$TOKEN" "$BASE/index.php?p="
实测回显(URL 指向本机/127 地址时的防护拦截):
{"fail":{"message":"URL is not allowed"}}
应用内置 SSRF 防护:拒绝 localhost、127.0.0.0/8 及 22/23/25/3306 等敏感端口(实测 127 回环被拒),公网 URL 正常拉取。
4.10 权限修改(chmod)
Web 界面点击 Perms 列的权限值进入九宫格复选框(owner/group/other × r/w/x)。接口用九个复选框字段表达八进制位(ur/uw/ux=属主读写执行,gr/gw/gx=组,or/ow/ox=其他):
# ur+uw+gr+gw = 0664
curl -s -b cj.txt -d "chmod=welcome.md&ur=1&uw=1&gr=1&gw=1&p=&token=$TOKEN" -L "$BASE/index.php?p=" -o /dev/null
stat -c '%a' ./data/welcome.md
实测回显(宿主侧权限确认生效):
664
4.11 Settings 面板
界面 Settings 可改语言/主题/显示隐藏文件/隐藏列,保存即写回 config.php 的 $CONFIG 行(写回机制与实测回显见《Tiny File Manager 2.6 配置参数详解》3.2)。接口形态(返回 1 即保存成功):
curl -s -b cj.txt -d "ajax=1&type=settings&js-language=zh-CN&js-error-report=false&js-show-hidden=true&js-hide-cols=false&js-theme-3=dark&token=$TOKEN" "$BASE/index.php?p="
实测回显:
1
4.12 只读账号的行为差异
用只读账号 user / 12345 登录(会话准备流程同第三节,替换用户名密码),实测确认:
- 目录浏览、搜索、下载三类操作正常(列表页正常渲染);
- 界面上写操作入口(Upload/New Item/批量 Delete/Zip 等)不渲染,条目操作列只剩「查看(view)」与「下载(dl)」两类链接(实测页面统计确认);
- 即使直连接口发起写操作,服务端也拦截(写端点统一带
!FM_READONLY前置判断)。
五、注意事项
- token 与会话绑定:换 cookie 必须重新取 token;登出后旧会话立即失效(实测:登出后继续用旧 cookie 操作,页面静默无消息);
- 删除与覆盖不可逆:删除、移动覆盖均无确认弹窗(界面端有 Are you sure 确认框,接口端没有)——脚本化操作前先备份;
- 打包/解压是同步操作:大目录打包会占住 PHP 单进程(内置服务器无并发),期间页面无响应,生产大目录建议在服务器命令行完成打包后刷新;
- 上传受三层限制:
$upload_chunk_size_bytes(分片)、$max_upload_size_bytes(应用层)、PHPupload_max_filesize/post_max_size(运行时),大文件失败逐层排查(参数见配置详解篇 5.5); - 接口自动化的会话管理:curl 会话 cookie 过期(默认 PHP session 生命周期)后所有操作静默退回登录页,脚本里应对每个响应做「是否含 fm_usr 登录框」的判断并自动重登。
六、常见问题
Q1:curl 操作全部「静默无效」没有报错?
按顺序排查三个高频原因(均为实测踩坑):POST 地址没带 ?p=(被 302 丢数据);token 放在 URL 而不是 POST 表单(部分端点不认);会话已过期或登出(响应其实是登录页)。
Q2:搜索没有结果?
type=search 的 path 参数取值 .(根)或子目录相对路径;content 是子串匹配(非正则)。确认目标文件在搜索起点之下,且 $exclude_items 没有把它排除。
Q3:移动/复制提示已存在?
目标目录(p)下已有同名条目。应用不会自动重命名,先删除/改名目标,或把源改名后再移动(实测复现)。
Q4:上传后文件名变成一串时间戳?
multipart 请求缺 fullpath 字段(见 4.9 排障实录),补上目标文件名即可。
Q5:界面里改了文件但宿主侧看不到/重启后丢了?
$root_path 没有指向挂载卷——文件写进了应用目录的可写层。解决与完整排障过程见部署指南 5.2。