最近想使用宝塔api来完成一些自动化的操作,发现官方文档对于较新接口没有文档,我就模仿官方的风格自己写了一份。
由于目前我主要用到文件接口,后续用到其他接口的时候,会逐步把这个文档补全。
官方文档链接:https://www.bt.cn/data/api-doc.pdf
注意:所有数据都经过了脱敏处理,而且为了最好的呈现接口请求和返回的数据,可能会存在部分数据对不上的情况。
宝塔版本:9.1.0
获取目录内容
URI地址:/files?action=GetDirNew
说明:查询指定目录下的文件和文件夹
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
p | 1 | number | 当前分页 | 是 |
showRow | 500 | number | 每一页显示多少 | 是 |
path | /www/wwwroot/test.com/aaa | string | 查询的文件夹目录 | 是 |
search | a.tar.gz | string | 搜索文件或者目录 | 否 |
all | true | bool | 是否搜索子目录 | 否 |
返回示例:
{
// 未知
"store": [],
// 未知
"file_recycle": true,
// 前端分页器显示使用
"page": "<div><span class='Pcurrent'>1</span><span class='Pnumber'>1/1</span><span class='Pline'>从1-2条</span><span class='Pcount'>共2条</span></div>",
// 当前路径
"path": "/www/wwwroot/test.com/aaa",
// 当前路径下的文件夹列表
"dir": [
{
"nm": "01", // 文件名
"sz": 4096, // 文件大小
"mt": 1721820262, // 文件创建时间
"acc": "755", // 文件权限
"user": "www", // 文件所属用户
"lnk": "",
"durl": "",
"cmp": 0,
"fav": "0",
"rmk": "", // 文件备注
"top": 0, // 文件是否置顶
"sn": "01"
},
],
// 当前路径下的文件列表
"files": [
{
"nm": "a.tar.gz",
"sz": 489171,
"mt": 1723080431,
"acc": "755",
"user": "www",
"lnk": "",
"durl": "",
"cmp": 0,
"fav": "0",
"rmk": "",
"top": 0,
"sn": "fangyu_0_0_3.tar.gz"
}
],
// 文件夹访问历史记录
"dir_history": [
{
"val": "/www/wwwroot", // 访问内容
"time": 1714820346 // 访问时间
}
],
// 文件搜索历史记录
"search_history": [
{
"val": "a.tar.gz", // 搜索内容
"time": 1723082202 // 搜索时间
}
],
// 未知
"tamper_data": {
"status": false,
"msg": "插件不存在!"
},
// 未知
"bt_sync": []
}
检测文件是否存在
URI地址:/files?action=upload_files_exists
说明:用于检测一个或者多个文件是否已经存在,一般在上传文件之前检测
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
files | /www/wwwroot/test.com/1.jpg\n/www/wwwroot/test.com/2.jpg | string | 文件的绝对路径,多个文件用换行符分割 | 是 |
返回示例:
[
{
"filename": "/www/wwwroot/test.com/1.jpg", // 文件名
"exists": false, // 文件是否存在
"size": 0, // 文件大小
"mtime": 0, // 文件上传时间
"isfile": false // 是否为文件
},
{
"filename": "/www/wwwroot/test.com/2.jpg",
"exists": true,
"size": 489380,
"mtime": 1723079747,
"isfile": true
}
]
上传文件
URI地址:/files?action=upload
说明:用于上传单个文件
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
f_path | /www/wwwroot/test.com/ | string | 上传此目录 | 是 |
f_name | 3.jpg | string | 上传文件名 | 是 |
f_size | 102340 | number | 文件大小(字节单位) | 是 |
f_start | 0 | number | 默认为0,意义不明 | 是 |
blob | (二进制) | stream | 字节流,文件内容 | 是 |
request_time | 1723082316467 | number | 上传时间 | 是 |
request_token | d199a518eda49a2617a4c35c37ee0330 | string | 请求token,意义不明 | 是 |
返回示例:
{
"status": true, // 用于说明上传是否成功
"msg": "上传成功!" // 前端显示消息
}
补充说明:
request_token 字段的计算方式我在源码里面找到了,window.vite_public_proxy_key 为空字符串
function getToken() {
const e = Date.now(), t = window.vite_public_proxy_key;
return {
requestTime: e,
requestToken: md5(String(e).concat(md5(t)))
}
}
下面是等价的 python 代码 (3.10版本)
import hashlib
import time
def get_token():
request_time = int(time.time() * 1000)
proxy_key = ''
token_string = str(request_time) + hashlib.md5(proxy_key.encode()).hexdigest()
request_token = hashlib.md5(token_string.encode()).hexdigest()
return {
"requestTime": request_time,
"requestToken": request_token
}
宝塔api
获取目录内容
URI地址:/files?action=GetDirNew
说明:查询指定目录下的文件和文件夹
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
p | 1 | number | 当前分页 | 是 |
showRow | 500 | number | 每一页显示多少 | 是 |
path | /www/wwwroot/test.com/aaa | string | 查询的文件夹目录 | 是 |
search | a.tar.gz | string | 搜索文件或者目录 | 否 |
all | true | bool | 是否搜索子目录 | 否 |
返回示例:
{
// 未知
"store": [],
// 未知
"file_recycle": true,
// 前端分页器显示使用
"page": "<div><span class='Pcurrent'>1</span><span class='Pnumber'>1/1</span><span class='Pline'>从1-2条</span><span class='Pcount'>共2条</span></div>",
// 当前路径
"path": "/www/wwwroot/test.com/aaa",
// 当前路径下的文件夹列表
"dir": [
{
"nm": "01", // 文件名
"sz": 4096, // 文件大小
"mt": 1721820262, // 文件创建时间
"acc": "755", // 文件权限
"user": "www", // 文件所属用户
"lnk": "",
"durl": "",
"cmp": 0,
"fav": "0",
"rmk": "", // 文件备注
"top": 0, // 文件是否置顶
"sn": "01"
},
],
// 当前路径下的文件列表
"files": [
{
"nm": "a.tar.gz",
"sz": 489171,
"mt": 1723080431,
"acc": "755",
"user": "www",
"lnk": "",
"durl": "",
"cmp": 0,
"fav": "0",
"rmk": "",
"top": 0,
"sn": "fangyu_0_0_3.tar.gz"
}
],
// 文件夹访问历史记录
"dir_history": [
{
"val": "/www/wwwroot", // 访问内容
"time": 1714820346 // 访问时间
}
],
// 文件搜索历史记录
"search_history": [
{
"val": "a.tar.gz", // 搜索内容
"time": 1723082202 // 搜索时间
}
],
// 未知
"tamper_data": {
"status": false,
"msg": "插件不存在!"
},
// 未知
"bt_sync": []
}
检测文件是否存在
URI地址:/files?action=upload_files_exists
说明:用于检测一个或者多个文件是否已经存在,一般在上传文件之前检测
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
files | /www/wwwroot/test.com/1.jpg\n/www/wwwroot/test.com/2.jpg | string | 文件的绝对路径,多个文件用换行符分割 | 是 |
返回示例:
[
{
"filename": "/www/wwwroot/test.com/1.jpg", // 文件名
"exists": false, // 文件是否存在
"size": 0, // 文件大小
"mtime": 0, // 文件上传时间
"isfile": false // 是否为文件
},
{
"filename": "/www/wwwroot/test.com/2.jpg",
"exists": true,
"size": 489380,
"mtime": 1723079747,
"isfile": true
}
]
上传文件
URI地址:/files?action=upload
说明:用于上传单个文件
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
f_path | /www/wwwroot/test.com/ | string | 上传此目录 | 是 |
f_name | 3.jpg | string | 上传文件名 | 是 |
f_size | 102340 | number | 文件大小(字节单位) | 是 |
f_start | 0 | number | 默认为0,意义不明 | 是 |
blob | (二进制) | stream | 字节流,文件内容 | 是 |
request_time | 1723082316467 | number | 上传时间 | 是 |
request_token | d199a518eda49a2617a4c35c37ee0330 | string | 请求token,意义不明 | 是 |
返回示例:
{
"status": true, // 用于说明上传是否成功
"msg": "上传成功!" // 前端显示消息
}
补充说明:
request_token 字段的计算方式我在源码里面找到了,window.vite_public_proxy_key 为空字符串
function getToken() {
const e = Date.now(), t = window.vite_public_proxy_key;
return {
requestTime: e,
requestToken: md5(String(e).concat(md5(t)))
}
}
下面是等价的 python 代码 (3.10版本)
import hashlib
import time
def get_token():
request_time = int(time.time() * 1000)
proxy_key = ''
token_string = str(request_time) + hashlib.md5(proxy_key.encode()).hexdigest()
request_token = hashlib.md5(token_string.encode()).hexdigest()
return {
"requestTime": request_time,
"requestToken": request_token
}
批量操作文件
URI地址:/files?action=SetBatchData
说明:当操作文件大于一个的时候,调用此接口
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
data | [“index.html”,“favicon.ico”] | string_array | 操作的文件名数组 | 是 |
type | 4 | number | 文件操作类型 | 是 |
path | /www/wwwroot/veys.qadub.monster/ | string | 操作的路径 | 是 |
user | www | string | 修改权限时,新的所属用户 | 否 |
access | 755 | string | 修改权限时,新的访问控制规则 | 否 |
all | true | bool | 修改权限时,是否递归修改文件夹 | 否 |
类型常量说明:
1 批量复制文件
2 批量剪切文件
3 批量修改文件权限
4 批量删除文件
返回示例:
{
"status": true, // 用于说明操作是否成功
"msg": "已批量将2个文件或目录移动到回收站" // 前端显示消息
}
获取文件内容
URI地址:/files?action=GetFileBody
说明:获取指定文件的内容
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
path | /www/wwwroot/test.com/index.html | string | 要获取文件的绝对路径 | 是 |
返回示例:
{
"status": true, // 说明接口请求是否成功
"only_read": false, // 是否为只读文件
"size": 205, // 文件大小, 字节单位
"encoding": "utf-8", // 文件编码方式
// 文件的内容
"data": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Document</title>\n</head>\n<body>\n \n</body>\n</html>",
"historys": ["1723157356"], // 文件修改历史记录
"auto_save": null, // 自动保存, 不知道用途, 可能是新版本的功能
"st_mtime": "1723157356" // 修改时间
}
保存文件内容
URI地址:/files?action=GetFileBody
说明:获取指定文件的内容
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
path | /www/wwwroot/test.com/index.html | string | 要保存文件的绝对路径 | 是 |
data | test | string | 新的文件内容 | 是 |
encoding | utf-8 | string | 新的文件编码 | 是 |
st_mtime | 1723158504 | number | 修改时间戳 | 是 |
force | 0 | number | 源码常数为0,意义未知 | 是 |
返回示例:
{
"status": true, // 说明接口请求是否成功
"msg": "文件已保存!", // 前端显示消息
"historys": [ // 文件修改历史记录
"1723158907",
"1723158504",
"1723157356"
],
"st_mtime": "1723158907" // 文件修改时间
}
添加文件修改记录
URI地址:/files?action=file_history
说明:修改文件时调用此接口,添加文件修改记录
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
name | undefined | string | 意义未知 | 是 |
path | /www/wwwroot/test.com/index.html | string | 修改文件的绝对路径 | 是 |
返回示例:
{
"status": true, // 用于说明操作是否成功
"msg": "添加成功" // 前端显示消息
}
移动和重命名文件
URI地址:/files?action=MvFile
说明:重命名文件时调用
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
sfile | /www/wwwroot/test.com/index.html | string | 老文件路径 | 是 |
dfile | /www/wwwroot/test.com/index.html.bak | string | 新文件路径 | 是 |
rename | true | bool | 是否重命名 | 否 |
补充说明:
rename 在剪切到不同目录时,是不用传递的。只有对文件重命名时需要传递。
如果剪切文件粘贴到原来的目录,也是需要传递的,猜测宝塔底层可能把这种行为处理为重命名了。
返回示例:
{
"status": true, // 用于说明操作是否成功
"msg": "重命名成功!" // 前端显示消息
}
复制文件
URI地址:/files?action=CopyFile
说明:复制文件时调用
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
sfile | /www/wwwroot/test.com/01/index.html | string | 老文件路径 | 是 |
dfile | /www/wwwroot/test.com/02/index.html | string | 新文件路径 | 是 |
返回示例:
{
"status": true, // 用于说明操作是否成功
"msg": "文件复制成功!" // 前端显示消息
}
删除文件
URI地址:/files?action=DeleteFile
说明:删除文件时调用
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
path | /www/wwwroot/test.com/index.html | string | 删除文件路径 | 是 |
返回示例:
{
"status": true, // 用于说明操作是否成功
"msg": "已将文件移动到回收站!" // 前端显示消息
}
检查目录是否存在
URI地址:/files?action=test_path
说明:删除文件时调用
请求参数:
参数名称 | 参数示例值 | 参数类型 | 说明 | 是否必传 |
---|---|---|---|---|
path | /www/wwwroot/test.com/ | string | 要检查的目录 | 是 |
返回示例:
// 存在的返回值
{
"path": "/www/wwwroot/test.com/", // 目标路径
"is_dir": true, // 是否为目录
"exists": true // 是否存在
}
// 不存在的返回值
{
"path": "",
"is_dir": null,
"exists": false
}