TR069 API 接口 V1.3
更新说明
日期 |
更新说明 |
---|---|
2025/01/21 |
V1.3 新增 2.10 -> 光猫固件升级 |
2024/09/10 |
V1.2 新增 自助修改光猫 WiFi 配置 |
2024/07/10 |
V1.1 新增 CURL 例子及 API 客户端 HTML 源码 |
2023/11/23 |
V1.0 初次发布 |
1. 方法及参数
项目 |
描述 |
---|---|
通信协议 |
HTTP/1.1标准协议,如需加密,请使用HTTPS连接。 |
请求方法 |
GET 或 POST,某些特殊操作(比如上传文件)只支持POST,具体请见相关说明。 |
编码类型 |
传递参数及返回数据统一使用UTF-8编码。 |
数据格式 |
JSON |
请求URL格式 |
/api/<api_name>?参数1=值1&参数2=值2&… |
CORS跨域 |
支持 |
服务器响应头 |
Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * |
1.1. 数据类型
数据类型 |
描述 |
说明 |
---|---|---|
string |
字符串 |
如 hello |
int |
整型数字 |
如 -1 或 123 |
datetime |
日期时间 |
格式 yyyy-mm-dd HH:MM:SS 如 2020-01-01 10:08:20 |
bool |
布尔型 |
true/false 或 yes/no |
float |
浮点数字 |
如 0.123 |
text |
textarea文本 |
带换行符的多行文本,提交时需使用 encodeURIComponent 对内容进行编码 |
备注
encodeURIComponent 是 JavaScript 对统一资源标识符(URI)的组成部分进行编码的方法,兼容 RFC 3986 编码规范, 转义除了 字母 数字 ( ) . ! ~ * ' - 和 _ 之外的所有字符。
RFC3986 编码规范参考 1.3.4 节
1.2. Token 方式认证
Token 方式是一种快速简单的认证,无需计算签名,只需在每个请求加上固定的 Token 信息即可。
Token 方式只有装维权限,具体如下:
创建工单
选择已有模块,下发配置
修改单个光猫的某项配置(超管账号密码/WiFi/电话/PPPoE 账号密码)
查询类操作(如超管账号密码/WiFi 配置/WAN 业务等)
重启/复位光猫
备注
若需要完整的 TR069 操作权限,请使用 AppID 方式。
1.2.1. 获得 Token
Token 是一个 32 位的字符串,从 TR069 服务端生成的二维码中获取。

二维码内容:
https://ip 或域名:端口/?token=${token}
例如:
https://192.168.100.254/?token=36f3db18801d8ba28573a6511c788899
1.2.2. 举例
请求 API 时:
GET 请求 URI 参数中带上 token=${token}
POST 请求 Header 加上 X-Token=${token}
例子:
https://192.168.100.254/api/post_tr069?o=stat&token=36f3db18801d8ba28573a6511c788899
curl -k -d "o=stat" -H "X-Token: 36f3db18801d8ba28573a6511c788899" https://192.168.100.254/api/post_tr069
1.2.3. 典型业务流程
TR069 服务器上配置装维账号,开通对应权限,生成装维入口二维码
- APP 登录
可扫描二维码登录
手动输入服务器内网或云登录地址登录
- 调用 TR069 设备列表 API
显示在线的光猫
显示已创建好的模版(无需在 App 中创建)
选择光猫,下发指定模版
- 扫描光猫背面的零配置二维码(首选)或 SN 条形码,或设备标识条形码
手动输入房间号信息
选择模版,创建工单
- 光猫常见操作:
查询详细信息
查询超管账号密码
修改超管账号密码
重启、复位
通过 OLT 重启、禁用光猫、删除光猫注册等
1.3. AppID 方式访问API接口
所有的API请求均需认证,除明确说明外。
1.3.1. 创建API 账号
进入“系统”-》“登录管理”-〉“登录账号”,创建账号等级为“API 访问的账号”

对应关系如下:
AppID = apitest 账号
AppKey = 14e1b600b1fd579f47433b88e8d85291 明文密码2次MD5后的值
JavaScript 示例:
function doubleMd5(value) {
return CryptoJS.MD5(CryptoJS.MD5(value).toString()).toString();
}
1.3.2. 公共参数
字段名 |
字段含义 |
数据类型 |
---|---|---|
AppID |
API 账号名 |
string |
Time |
时间戳(秒) |
int |
Signature |
签名 |
string |
token |
随机字符串,长度6-8,字母数字组成 |
string |
注意
客户端需要保证生成的时间与服务端的时间相差不超过15分钟,否则服务端将拒绝此次请求。
1.3.3. 签名
为保证API的安全调用,系统会对每个API请求通过签名(Signature)进行身份验证。
Signature = md5(KV + '&' + AppKey)
KV = k1=v1&k2=v2&...&kn=vn
KV:对于除Signature外的每一个参数,生成一个子串${key}=${value},并按参数名从小到大排序(字母顺序),最后用&符号连接。
注意:如果参数值${value}中包含除【大小写字母/数字/减号/下划线/圆点/波浪号】外的字符,需要使用URL Encode对其进行编码。
重要
AppKey 不在网络中传递,仅作计算签名用!
1.3.4. URL Encode编码
使用UTF-8字符集按照《RFC3986规则》编码参数值,编码规则如下:
- 字符 A~Z、a~z、0~9 以及字符 - _ . ~ 不编码
- 其它字符编码成%XY的格式,其中XY是字符对应ASCII码的16进制表示,如英文双引号"对应的编码为%22
- 英文空格要编码成%20,而不是加号+
原始字符串:测试Hello World123-_.~!
编码后:%E6%B5%8B%E8%AF%95Hello%20World123-_.~%21
1.3.5. 举例
项目 |
值 |
---|---|
服务器地址 |
https://your.cloud.com |
API 路径 |
/api/my_profile |
AppID |
19216888001 |
AppKey |
c1853bef43910d487bdbffbde501e5d8 |
当前时间戳 |
1710991090 |
token |
123456 |
参数 |
o=show_all |
待签名字符串 |
AppID=19216888001&Time=1710991133&k2=%E6%B5%8B%E8%AF%95 &o=show_all&token=123456&c1853bef43910d487bdbffbde501e5d8 |
Signature 签名 |
d289fbe12c2fe69a5a62bfa2fd050fa3 |
最终请求URL |
https://your.cloud.com/api/my_profile?AppID=19216888001&Time=1710991133 &k2=%E6%B5%8B%E8%AF%95&o=show_all&token=123456 &Signature=d289fbe12c2fe69a5a62bfa2fd050fa3 |
CURL POST 例子:
curl -X POST https://your.cloud.com/api/my_profile \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'AppID=19216888001&Time=1710991133&k2=%E6%B5%8B%E8%AF%95&
o=show_all&token=123456&Signature=d289fbe12c2fe69a5a62bfa2fd050fa3'
1.4. 服务器响应
除特殊说明外, 所有请求均会返回 code 及 result。
响应数据 JSON 格式:
{
code: 代码,
result: 详细信息
}
代码含义:
code 值 |
说明 |
---|---|
0 |
操作失败 |
1 |
操作成功 |
-2 |
无操作权限 |
-3 |
输入参数包含非法字符,或格式不正确 |
-4 |
参数配置错误 |
-400 |
查询的对象不存在 |
10 |
无修改 |
-5004 |
客户端和服务端时差过大,需校准时间后重新请求 |
-5002 |
API 账号不存在 |
-5003 |
操作无权限 |
-5010 |
签名校验错误 |
2. TR069 API 列表
API 名:post_tr069,本节中除特别注明外,均调用此 API。
2.1. TR069 服务参数
配置 TR069 服务器运行参数
传递参数:
字段名 |
字段描述 |
数据类型 |
必须 |
说明 |
---|---|---|---|---|
o |
动作 |
string |
* |
固定为 srvconfig |
acs_server |
ACS 地址 |
string |
* |
域名或 IP,默认为 0.0.0.0 x.x.x.x 表示不下发 ACS 地址 |
acs_port |
监听端口 |
string |
* |
多个端口逗号分隔 |
report_interval |
设备周期上报时间间隔 |
int |
* |
单位:秒,范围30-28800,默认60 |
rxpower_range |
接收光功率正常范围 |
string |
单位:dBm,默认 -27,-8 |
|
txpower_range |
发送光功率正常范围 |
string |
单位:dBm,默认 0.5,5 |
|
current_range |
偏置电流正常范围 |
string |
单位:mA,默认 0,90 |
|
vcc_range |
供电电压正常范围 |
string |
单位:mV,默认 3100,3500 |
|
temp_range |
工作温度正常范围 |
string |
单位:°C,默认 -10,85 |
|
weixin_alert |
启用设备告警微信通知 |
bool |
yes/true=是,其他值=否 |
|
ont_offline_reboot |
异常离线重启 |
bool |
设备异常离线通过 OLT 重启恢复 |
|
autorm_offline |
自动清除离线设备 |
bool |
||
wan_access |
允许通过 WAN 口访问 |
bool |
2.2. 查询相关操作
2.2.1. 获得设备列表
返回光猫设备列表
传递参数:
字段名 |
字段描述 |
数据类型 |
必须 |
说明 |
---|---|---|---|---|
o |
动作 |
string |
* |
固定为 stat |
k |
搜索关键字 |
string |
全局搜索 |
|
sort |
排序属性 |
string |
默认为 uuid |
|
rsort |
反向排序 |
int |
1=反向排序,默认为 0 |
|
pmax |
每页显示数量 |
int |
默认 10 |
|
page |
页码 |
int |
默认 1 |
|
status |
在线状态 |
int |
1=在线,0=离线 |
|
cfgstat |
配置下发状态 |
int |
1=已下发,0=未下发 |
|
ponstat |
光模块状态 |
int |
1=正常,0=异常,-1=无光模块信息 |
|
hwver |
硬件版本 |
string |
||
softver |
软件版本 |
string |
||
group |
分组 |
string |
特殊分组:
|
|
iface_xxx |
网络接口 xxx |
string |
||
sipstat |
语音注册状态 |
string |
|
|
has_loid |
LOID 状态 |
string |
1=有 LOID,0=无 LOID |
|
isp |
运营商 |
string |
|
|
bizp |
已下发业务模版 |
string |
||
pppoeuser |
PPPoE 账号 |
int |
1=有账号,0=无账号 |
|
ppp_stat |
PPPoE 拨号连接状态 |
string |
|
|
ppp_err |
PPPoE 拨号失败错误原因 |
string |
|
返回数据:
{
"ENABLE": "yes", // 启用 TR069 管理
"page": 1, // 当前页码
"pages": 2, // 总页数
"pmax": 10, // 每页显示数量
"total": 15, // 当前符合条件的设备数量
"total_onts": 15, // 总设备数量
"running_jobs": "0", // 正在下发的任务数
"deploy_jobs": "0", // 等待下发的任务数
"license_num": "0", // 授权数量(0表示无限制)
"yunmgr_ok": 1, // 云平台连接状态(1表示正常)
"softvers": [ // 软件版本列表
"G230T224R1.0.0",
//...
],
"groups": [ // 分组列表
"CIOT#GM220-S",
//...
],
"hwvers": [ // 硬件版本列表
"1.0",
//...
],
"ifaces": [ // 请求来源网络接口列表
"lan1.46",
//...
],
"bizps": [ // 已下发业务模版列表
"桥接模式",
//...
],
"srvconfig": { // 服务参数(参考2.1字段说明)
"acs_port": "9090,8012,5481,9092,8088",
"acs_server": "x.x.x.x",
"autorm_offline": "yes",
"current_range": "0,90",
"ont_offline_reboot": "no",
"report_interval": "60",
"rxpower_range": "-27,-8",
"temp_range": "-10,85",
"txpower_range": "0.5,5",
"vcc_range": "3100,3500",
"wan_access": "no",
"weixin_alert": "yes"
},
"data": [ // 设备列表
{
"accesstype": "GPON", // PON类型
"acs_url": "http://192.168.46.1:9090", // ACS 地址
"addtime": "2023-11-08 15:58:05", // 加入时间
"bizp": "桥接模式", // 下发模版
"capability": "1;4GE;;1;1", // 设备能力
"cfgstat": 1, // 是否已下发配置
"uuid": "EC8AC7-FHTT69E9A450", // 设备唯一标识
"oui": "EC8AC7", // 厂商ID
"serialnumber": "FHTT69E9A450", // 设备SN
"manufacturer": "FiberHome", // 生产厂家
"productclass": "HG6145D1", // 光猫型号
"hwver": "WKE2.094.392", // 硬件版本
"softver": "RP0301", // 软件版本
"macaddress": "B4-60-8C-E9-A4-50", // MAC地址
"ont_sn": "4648545469E9A450", // OLT 上注册SN
"olt_location": "192.168.100.56 gpon 0:1:1:12", // OLT 位置
"devicetype": "HG6145D1",
"description": null,
"logtime": "2023-11-21 16:16:53", // 最后在线时间
"loid": null, // LOID
"report_interval": "60", // 周期汇报时间间隔
"desc": "", // 备注
"room": null, // 房间号
"isp": "X_CMCC", // 运营商
"doing": "",
"exptime": null,
"geo": null, // IP地理位置
"grp": "g1p", // 分组
"id": 1, // 编号
"iface": "lan2.46", // 汇报来源接口
"inetip": "2001:db8:46::e2f3", // TR069 管理IP
"submit_ip": "2001:db8:46::e2f3", // 汇报来源IP
"init_acs": null, // 初始ACS地址
"lan_port": [ // LAN口网线状态
{
"name": "LAN1",
"value": "Up" // Up=已连接
},
{
"name": "LAN2",
"value": "NoLink" // NoLink=未连接
},
//...
],
"lanip": "192.168.1.1", // LAN口IP
"ponstat": 1,
"ppp_err": null, // PPPoE 拨号错误
"ppp_stat": null, // PPPoE 连接状态
"pppoepass": null, // PPPoE 拨号密码
"pppoeuser": null, // PPPoE 拨号用户名
"psk_passwd": null,
"psk_passwd_5g": null,
"running_status": "online", // 运行状态
"sip_lines": "1", // 电话线路数量
"phone_number_<N>": "666", // 电话线路<N>对应的号码(N=1~16)
"phone_stat_<N>": "Up", // 电话线路<N>注册状态
"sip1": "666",
"sip1pass": "",
"sip2": "",
"sipstat": "Registering",
"ssid1": "IPv6Test-2.4G",
"ssid2": "CMCC-Gabr-2",
"ssid_5g1": "IPv6Test-5G",
"ssid_5g2": "CMCC-Gabr-6",
"status": "1", // 在线状态(1=在线,0=离线)
"uptime": 1022085, // 运行时长
"wanconns": 2, // WAN 业务数量
"wancount": 2,
"wifi": [
{
"type": "2.4G", // 无线协议类型(2.4G)
"channel": "13", // 信道
"clientcount": 0, // 连接终端数量
"enable": 1, // 启用状态(1=启用,0=禁用)
"encrypt": "WPA/WPA2", // 加密方式(None=不加密)
"hidessid": 1, // 隐藏SSID(1=隐藏)
"id": 1, // SSID 序号
"name": "ssid1", // SSID 编号
"index": "2.1", // SSID 索引(A.B)
"ssid": "IPv6Test-2.4G", // SSID 名称
"status": "Up" // 无线状态
},
{
"channel": "157",
"clientcount": 0,
"enable": 1,
"encrypt": "WPA/WPA2",
"id": "5",
"index": "5.1",
"name": "ssid5",
"ssid": "IPv6Test-5G",
"status": "Up",
"type": "5.8G" // 5.8G 无线
},
//...
],
"wifi_passwd": "1=12345678|5=12345678", // WIFI 密码
"wifi_ssid_list": "1,2,3,4,5,6,7,8", // WIFI SSID 列表
"xpon_current": "11.9", // 电流
"xpon_rx": "-13.5", // 收光功率
"xpon_temp": "40.7", // 光模块温度
"xpon_tx": "2.0", // 发光功率
"xpon_vcc": "3338.4" // 电压
},
//...
],
"app_update": { // APP 更新信息
"clog": "首次发布", // 更新日志
"rtime": "2022-04-28 10:00:00", // 发布时间
"url": "https://app.com/tr069-1.0.0.apk", // 下载地址
"ver": "1.0.0" // 版本号
}
}
2.2.2. 查询 WAN 业务详情
获得指定光猫的 WAN 连接列表,包括连接状态、VLAN、业务类型等。
传递参数:
字段名 |
字段描述 |
数据类型 |
必须 |
说明 |
---|---|---|---|---|
o |
动作 |
string |
* |
固定为 get_wan |
target |
设备 UUID |
string |
* |
返回数据:
{
"code": 1,
"iface": "lan2.46", // 来源接口
"tr069_inetip": "2001:db8:46::e2f3", // TR069 WAN 连接 IP
"tr069_wanip": "2001:db8:46::e2f3", // TR069 汇报来源IP
"data": [ // WAN 连接列表
{
"address_type": "DHCP", // 地址类型
// Static=固定IP,DHCP=动态获取
"bridge_ports": "",
"dhcpserver": "yes",
"dns": "0.0.0.0,0.0.0.0",
"enable": "yes", // 启用WAN连接
"enable_nat": "no",
"gateway": "0.0.0.0",
"id": "IP1", // WAN 编号
"ip": "0.0.0.0",
"ip6": "2001:db8:46::e2f3", // IPv6 地址
"ip6_dns": "2001:db8:46::1,2001:db8:46::1", // IPv6 DNS
"ip6_status": "Connected", // IPv6 连接状态
// Connected=已连接,Connecting=连接中
"ipmode": "2", // IP协议栈
// 1=IPv4,2=IPv6,3=IPv4+IPv6
"link_mode": "IP_Routed", // 连接模式
// IP_Routed=IP路由,PPPoE_Routed=PPPoE路由
// IP_Bridged=IP桥接,PPPoE_Bridged=PPPoE桥接
"mac": "B4:60:8C:E9:A4:52", // MAC地址
"mtu": "1492", // MTU
"multicast_vlan": "0", // 组播VLAN
"name": "1_TR069_R_VID_46", // 连接名称
"netmask": "0.0.0.0", // 子网掩码
// WAN连接完整属性名
"prefix": "WANDevice.1.WANConnectionDevice.1.WANIPConnection.1",
"service": "TR069", // 承载业务
"srvname": "X_CMCC_ServiceList", // 业务字段名
"status": "Connecting",
"uptime": "19334", // 已连接时长(秒)
"vlan_id": "46", // VLAN ID
"vlan_mode": "X_CMCC_VLANMode", // VLAN 模式字段
"vlan_name": "X_CMCC_VLANIDMark" // VLAN 名称字段
},
{
"address_type": "DHCP",
"bridge_ports": "LAN1,LAN2,LAN3,LAN4,WIFI1,WIFI5", // 绑定端口
"dhcpserver": "yes",
"dns": "119.29.29.29,180.76.76.76", // IPv4 DNS 服务器
"enable": "yes",
"enable_nat": "yes", // 启用 NAT
"gateway": "10.100.0.1", // IPv4 网关
"id": "IP2",
"ip": "10.100.0.130", // IPv4 地址
"ip6": "",
"ip6_dns": ",",
"ip6_status": "Connecting",
"ipmode": "1",
"link_mode": "IP_Routed",
"mac": "B4:60:8C:E9:A4:53",
"mtu": "1500",
"multicast_vlan": "-1",
"name": "4_VOIP_INTERNET_R_VID_100",
"netmask": "255.255.255.0",
"prefix": "WANDevice.1.WANConnectionDevice.1.WANIPConnection.2",
"service": "VOIP_INTERNET",
"srvname": "X_CMCC_ServiceList",
"status": "Connected", // 连接建立状态
"uptime": "64852",
"vlan_id": "100",
"vlan_mode": "X_CMCC_VLANMode",
"vlan_name": "X_CMCC_VLANIDMark",
"username": "", // PPPoE账号
"passwd": "", // PPPoE密码
"pppoe_error": "" // PPPoE拨号错误信息
},
//...
]
}
2.2.3. 查询 WiFi 配置
实时查询并获得指定光猫的 WiFi 配置,包括 SSID、信道、加密方式等。
传递参数:
字段名 |
字段描述 |
数据类型 |
必须 |
说明 |
---|---|---|---|---|
o |
动作 |
string |
* |
固定为 get_wlanconfig |
target |
设备 UUID |
string |
* |
|
id |
SSID 编号 |
int |
* |
范围:1-16,对应 设备列表中的 data->wifi->id 字段 |
返回数据:
{
"BSSID": "b4:61:8c:e9:a4:51", // BSSID
"BeaconType": "WPA/WPA2", // 加密类型(None=不加密)
"Channel": "1", // 信道
"ChannelWidth": "2", // 信道带宽
"Enable": "1", // 启用状态
"SSID": "IPv6Test-2.4G", // SSID 名称
"TransmitPower": "100", // 发射功率
"X_CMCC_ChannelWidth": "2", // 自定义信道带宽
"bandwidth": "auto", // 信道带宽
"code": 1,
"enable": "yes", // 启用 SSID
"id": "1", // SSID 编号
"psk_passwd": "12345678", // 密码
"type": "2.4G" // 无线协议类型(2.4G/5.8G)
}
2.2.4. 查询 SIP 配置
实时查询并获得指定光猫的语音配置,包括 SIP 服务器、端口、SIP 账号、注册状态等。
传递参数:
字段名 |
字段描述 |
数据类型 |
必须 |
说明 |
---|---|---|---|---|
o |
动作 |
string |
* |
固定为 get_sip |
target |
设备 UUID |
string |
* |
|
line |
线路编号 |
int |
* |
范围:1-16,1 表示第一个电话 |
返回数据:
{
"AuthPassword": "666", // SIP 密码
"AuthUserName": "666", // SIP 账号
"DigitMap": "[*#]x[0-9*].#|[0-9]X.", // 数图
"DigitMapEnable": "1", // 启用数图(1=启用)
"LastRegisterError": "访问路由不通", // 上一次注册错误信息
"RegistrarServer": "1.2.3.4", // SIP 服务器地址
"RegistrarServerPort": "5060", // SIP 服务器端口
"ServerType": "1", // 语音协议
// 语音协议: 0 = IMS SIP, 1 = 软交换 SIP, 2 = H.248
"Status": "Registering", // 注册状态
// Up=注册成功, Disabled=禁用, Registering=注册中, Error=错误
"UserAgentDomain": "fiberhome", // 用户域名
"code": 1,
"line": "1", // 线路编号
"sip_protocol_ok": 1
}
2.2.5. 查询超管账号密码
实时查询并获得指定光猫的超管 Web 登录账号、密码,支持批量查询。
传递参数:
字段名 |
字段描述 |
数据类型 |
必须 |
说明 |
---|---|---|---|---|
o |
动作 |
string |
* |
固定为 get_superpass |
target |
设备 UUID |
string |
* |
|
format |
输出格式 |
string |
* |
固定为 json |
返回数据:
{
"code": 1,
"data": [ // 查询结果
{
"passwd": "Admin@123", // 超管密码
"username": "CMCCAdmin", // 超管账号
"uuid": "6C0F0B-CMDCA20EF4CF" // 设备UUID
},
//...
]
}
2.2.6. 查询 Telnet
实时查询并获得指定光猫的 Telnet 账号和密码。
传递参数:
字段名 |
字段描述 |
数据类型 |
必须 |
说明 |
---|---|---|---|---|
o |
动作 |
string |
* |
固定为 get_telnet |
format |
格式 |
string |
* |
固定为 json |
target |
设备 UUID |
string |
* |
返回数据:
{
"code": 1,
"data": [ // 查询结果
{
"enable": 1, // Telnet 状态(1=已开启)
"passwd": "Fh@E9A451", // Telnet 密码
"port": "23", // Telnet 端口
"username": "admin", // Telnet 账号
"uuid": "EC8AC7-FHTT69E9A450" // 设备UUID
},
//...
]
}
2.2.7. 实时刷新光猫数据
实时从光猫获取最新状态和数据。
传递参数:
字段名 |
字段描述 |
数据类型 |
必须 |
说明 |
---|---|---|---|---|
o |
动作 |
string |
* |
固定为 refresh_onu |
target |
设备 UUID |
string |
* |
返回数据:
{
// 与 2.2.1 获得设备列表 返回 data 数组元素格式相同
"accesstype": "GPON",
"acs_url": "http://192.168.46.1:9090",
"addtime": "2023-11-08 15:58:05",
"bizp": "桥接模式",
"capability": "1;4GE;;1;1",
"cfgstat": 1,
//...
}
2.2.8. 获得模版列表
获得TR069配置模版(如LAN、WAN、语音等)、业务模版。
业务模版(type=business)是指一个完整的业务流程所需要的模版配置集合,一个业务模版包含多个配置模成员(member字段)。
API 名:config_tr069_profile
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
sort |
string |
排序 |
为空默认按name,可选:
|
|
rsort |
int |
反向排序 |
1=反向排序 |
|
pmax |
int |
显示数量 |
* |
固定为999 |
type |
string |
模版类型 |
按模版类型筛选 |
返回数据:
{
"code": 1,
"data": [ // 模版列表
{
"active": "yes", // 激活状态
"apmodule": "no",
"bandwidth": "auto",
"cipher": "auto",
"disable_wps": "no",
"enable": "yes",
"encrypt": "encrypt",
"hide_ssid": "yes",
"id": 1, // 编号
"name": "2.4G无线", // 模版名称
"psk_passwd": "12345678",
"ssid": "IPv6Test-2.4G",
"tpower": "0",
"type": "wlan0", // 模版类型
"desc": "" // 备注
},
{
"active": "yes",
"id": 9,
"member": "2.4G无线,5.8G无线", // 模版成员
"name": "无线业务",
"type": "business",
"desc": ""
},
//...
]
}
2.3. 常用光猫维护操作
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
见下 |
target |
string |
设备UUID |
* |
多个设备逗号分隔 |
动作 o 值:
enable_telnet 开启telnet
disable_telnet 关闭telnet
enable_wan_access 开启WAN侧访问光猫
disable_wan_access 关闭WAN侧访问
wifi_off 一键关闭WiFi(2.4G+5.8G)
wifi_on 一键启用WiFi(2.4G+5.8G)
rm_sip 禁用SIP电话
rm_wans 删除所有WAN业务(除TR069)
hack_limit 解除上网限制(将重启光猫)
del_onu 删除设备缓存
resetclear 恢复出厂并清零(不再接受汇报)
resetfactory 恢复出厂配置
resetfactory_deep 深度恢复出厂配置(清除LOID/PPPoE账号/SIP电话/重置超管密码)
reboot 重启光猫
reportnow 强制光猫主动上报一次 / 刷新光猫状态
sync_olt_info 同步OLT位置信息
del_olt_reg 删除OLT上光猫注册记录
del_by_olt 删除设备,同时删除OLT上光猫的注册记录
disable_by_olt 通过OLT禁用光猫
reboot_by_olt 通过OLT重启光猫
2.4. 配置相关操作
2.4.1. 修改超管账号密码
修改光猫的超管账号和密码。
传递参数:
字段名 |
字段描述 |
数据类型 |
必须 |
说明 |
---|---|---|---|---|
o |
动作 |
string |
* |
固定为 set_superpass |
target |
设备 UUID |
string |
* |
多个设备逗号分隔 |
passwd |
超管密码 |
string |
* |
数字、字母、@组成至少8位 |
2.4.2. 修改 WIFI 配置
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
set_wlan |
target |
string |
设备UUID |
* |
|
id |
int |
SSID 序号 |
* |
对应 2.2.1 设备列表 中 data->wifi->id 字段 |
ssid |
string |
WIFI 名称 |
* |
|
encrypt |
string |
加密方式 |
* |
为空表示自动
|
psk_passwd |
string |
密码 |
为空表示不修改 |
|
channel |
int |
信道 |
0或空表示自动,-1表示随机
|
|
enable |
bool |
启用SSID |
* |
|
tpower |
int |
发射功率 |
为空表示自动
|
提交后,需要5-10秒左右生效,需要稍后刷新光猫状态。
2.4.3. 修改 SIP 电话
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
set_sip |
target |
string |
设备UUID |
* |
|
line |
int |
线路ID |
* |
1-16,如1表示第一个电话 |
user |
int |
电话号码/SIP账号 |
* |
数字、字母、加减号、圆点、@组成 |
pass |
string |
SIP密码 |
* |
数字、字母、加减号、圆点、@、百分号组成 |
enable_digitmap |
bool |
启用数图 |
||
digitmap |
string |
数图规则 |
||
randpass |
bool |
随机密码 |
||
enable |
bool |
激活线路 |
* |
|
server_type |
string |
语音协议 |
* |
ims=IMS SIP,soft=软交换SIP 为空表示自动 |
提交后,需要5-10秒左右生效,需要稍后刷新光猫状态。
2.4.4. 修改 WAN PPPoE
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
set_wan_pppoe |
target |
string |
设备UUID |
* |
|
prefix |
string |
WAN 属性名 |
* |
对应 2.2.2 WAN业务详情 中返回的data->prefix字段 |
username |
string |
PPPoE 拨号账号 |
* |
数字、字母、减号、圆点、@组成 |
passwd |
string |
PPPoE 拨号密码 |
* |
数字、字母、减号、圆点、@组成 |
提交后,需要5-10秒左右生效,需要稍后刷新光猫状态。
2.4.5. 修改备注房间号
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
mark_onu |
target |
string |
设备UUID |
* |
|
room |
string |
房间号 |
数字、字母、减号、圆点、@组成 |
|
desc |
string |
备注 |
支持中文 |
2.5. 创建/修改工单
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
i |
string |
项目 |
* |
固定为 order |
uid |
string |
设备标识 |
* |
零配置二维码内容,或光猫SN、MAC |
room |
string |
房间号 |
数字、字母、减号、圆点、@组成 |
|
group_name |
string |
分组名 |
分组不存在时,将自动创建 |
|
desc |
string |
备注 |
支持中文 |
|
profile |
string |
配置/业务模版 |
* |
要下发的模版名 |
active |
bool |
激活 |
* |
|
wan_pppoe_user |
string |
PPPoE 账号 |
||
wan_pppoe_pass |
string |
PPPoE 密码 |
||
ssid |
string |
2.4G 无线名称 |
||
ssid_5g |
string |
5.8G 无线名称 |
||
channel |
string |
2.4G 无线信道 |
||
channel_5g |
string |
5.8G 无线信道 |
||
psk_passwd |
string |
2.4G 无线密码 |
||
psk_passwd_5g |
string |
5.8G 无线密码 |
||
deploy_on_reset |
bool |
复位自动下发 |
光猫复位后初次启动时自动下发模版 |
|
sip_account |
string |
SIP 账号信息 |
支持多行, 每行格式:账号 密码 如 8012 123456 |
|
oldname |
string |
工单oid |
仅修改工单时传递 |
2.6. 配置/模版下发
2.6.1. 下发模版
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
|
target |
string |
设备UUID |
* |
多个UUID逗号分隔 |
profile |
string |
模版名 |
* |
配置/业务模版名,对应 2.2.8 模版列表 中 data->name 字段 |
2.6.2. 下发自定义属性值
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
固定为 tr069_usercmd |
target |
string |
设备UUID |
* |
多个UUID逗号分隔 |
cmd |
text |
tr069参数值 |
* |
每行格式:key=value |
2.7. 诊断测试
2.7.1. WAN业务PING 测试
对指定 WAN 连接执行 PING 测试
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
diag_wan |
target |
string |
设备UUID |
* |
|
prefix |
string |
WAN 属性名 |
* |
对应 2.2.2 WAN业务详情 中返回的data->prefix字段 |
ping_target |
string |
PING目标 |
* |
域名或IP |
format |
string |
输出格式 |
* |
固定为 json |
返回数据:
{
"AverageResponseTime": "27", // 平均延时
"DataBlockSize": "56",
"FailureCount": "0", // 失败计数
"Host": "www.baidu.com", // PING 目标
"MaximumResponseTime": "27", // 最大延时
"MinimumResponseTime": "26", // 最小延时
"NumberOfRepetitions": "3", // 发送包数量
"SuccessCount": "3", // 成功回应数量
"code": 1,
"result": "PING 目标 www.baidu.com
发送包 3, 成功 3, 失败 0
最小/最大/平均延时 = 26/27/27 ms
"
}
2.8. 分组操作
2.8.1. 加入分组
将光猫加入指定分组。
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
固定为 add_mem |
target |
string |
设备UUID |
* |
多个UUID逗号分隔 |
to_group |
string |
分组名 |
* |
对应 2.2.2 WAN业务详情 中返回的data->groups 字段数组的元素 |
2.8.2. 移出分组
将光猫从指定分组中移出。
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
固定为 del_mem |
target |
string |
设备UUID |
* |
多个UUID逗号分隔 |
group |
string |
分组名 |
* |
对应 2.2.2 WAN业务详情 中返回的data->groups 字段数组的元素 |
2.9. 自助修改光猫WiFi
根据用户输入的光猫SN、PPPoE账号、光猫MAC、LOID 精确查询对应的光猫。
本节API无需常规的Token或AppID认证,传递任意token=值可跳过认证。
2.9.1. 精确查询光猫
API 名:post_tr069_user
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
固定为 get_onu |
token |
string |
任意字符串 |
* |
用于跳过认证 |
uuid |
string |
唯一设备ID |
||
sn |
string |
光猫SN |
||
pppoe_user |
string |
PPPoE拨号账号 |
||
mac |
string |
光猫MAC |
不区分大小写, 格式:001122AABBCC |
|
loid |
string |
光猫注册LOID |
uuid、sn、pppoe_user、mac、loid 5个参数至少有一个不为空。
查找优先级:uuid -> loid -> pppoe_user -> sn -> mac
返回数据:
{
"code": 1, // 返回0表示没有找到对应的光猫
// 与 2.2.1 获得设备列表 返回 data 数组元素格式相同
"uuid": "唯一设备ID",
"accesstype": "GPON",
"acs_url": "http://192.168.46.1:9090",
"addtime": "2023-11-08 15:58:05",
"bizp": "桥接模式",
"capability": "1;4GE;;1;1",
"cfgstat": 1
//...
}
例子:
按PPPoE账号查询:
https://192.168.201.1/api/post_tr069_user?o=get_onu&pppoe_user=a123456&token=any
按SN或PON SN查询:
https://192.168.201.1/api/post_tr069_user?o=get_onu&sn=FHTT8E931E70&token=any
https://192.168.201.1/api/post_tr069_user?o=get_onu&sn=464854548E931E70&token=any
按MAC查询:
https://192.168.201.1/api/post_tr069_user?o=get_onu&mac=24B7DA931E70&token=any
2.9.2. 修改WiFi参数
API 名:post_tr069_user
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
固定为 set_wifi |
token |
string |
任意字符串 |
* |
用于跳过认证 |
uuid |
string |
唯一设备ID |
* |
|
id |
int |
SSID 序号 |
* |
对应 2.2.1 设备列表 中 data->wifi->id 字段 |
ssid |
string |
WiFi 名称 |
* |
数字、字母、下划线、减号、圆点、@、中文汉字组成 |
psk_passwd |
string |
WiFi 密码 |
至少8位,数字、字母、下划线、减号、圆点、@组成,为空表示不修改密码 |
提交后,需要5-10秒左右生效,需要稍后刷新光猫状态(重新查询光猫信息)。
例子:
修改2.4G第一个SSID名为 hello2.4:
https://192.168.201.1/api/post_tr069_user?o=set_wifi&uuid=EC8AC7-FHTT8E931E70&id=1&ssid=hello2.4&psk_passwd=test123456&token=any
修改5.8G第一个SSID名为 5.8-测试:
https://192.168.201.1/api/post_tr069_user?o=set_wifi&uuid=EC8AC7-FHTT8E931E70&id=5&ssid=5.8-测试&psk_passwd=test123456&token=any
2.10. 光猫固件升级
API 名:post_tr069
传递参数:
字段名 |
字段类型 |
字段描述 |
必须 |
说明 |
---|---|---|---|---|
o |
string |
动作 |
* |
固定为 tr069_usercmd |
cmd |
string |
命令 |
* |
格式:ug=http://IP或域名[:可选端口]/文件路径 |
uuid |
string |
唯一设备ID |
* |
多个uuid逗号分隔 |
cmd 例子:ug=http://192.168.46.1/public/ug.bin
附录: API 客户端源码参考
源码文件下载地址:
https://ITMS服务器IP:端口/apidoc/tr069-api-get.html
https://ITMS服务器IP:端口/apidoc/tr069-api-post.html
tr069-api-get.html
HTTP GET 方式请求:
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>API 测试客户端</title>
6 <style>
7 body {
8 font-family: Arial, sans-serif;
9 }
10 form {
11 margin-bottom: 20px;
12 }
13 label {
14 display: block;
15 margin-top: 10px;
16 }
17 input, textarea, button {
18 display: block;
19 margin-top: 5px;
20 width: 100%;
21 max-width: 700px;
22 font-size: 16px;
23 padding: 10px;
24 }
25 textarea {
26 height: 150px;
27 }
28 .container {
29 margin-bottom: 20px;
30 }
31 </style>
32 <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
33</head>
34<body>
35 <h1>TR069 API 测试客户端 - GET 方式</h1>
36 <div class="container">
37 <label for="getUrl">GET 请求 URL:</label>
38 <input type="text" id="getUrl" name="getUrl" value="" required>
39 <label for="getApiPath">API 路径:</label>
40 <input type="text" id="getApiPath" name="getApiPath" value="/api/post_tr069" required>
41 <label for="getAppID">AppID:</label>
42 <input type="text" id="getAppID" name="getAppID" value="apitest" required>
43 <label for="getAppKey">AppKey:</label>
44 <input type="text" id="getAppKey" name="getAppKey" value="admin@123" required>
45 <button type="button" onclick="convertAppKey()">转换</button>
46 <label for="getTime">时间戳:</label>
47 <input type="text" id="getTime" name="getTime" value="1621500119" required>
48 <label for="getToken">Token:</label>
49 <input type="text" id="getToken" name="getToken" value="123456" required>
50 <label for="getStatus">在线状态:</label>
51 <input type="text" id="getStatus" name="getStatus" value="1" required>
52 <label for="getO">动作参数:</label>
53 <input type="text" id="getO" name="getO" value="stat" required>
54 </div>
55 <div class="container">
56 <label for="signingString">待签名的 URL 字符串:</label>
57 <textarea id="signingString" rows="4" readonly></textarea>
58 <button type="button" onclick="generateSignature()">生成签名</button>
59 <label for="signature">签名:</label>
60 <input type="text" id="signature" readonly>
61 </div>
62 <div class="container">
63 <label for="generatedUrl">生成的完整 URL:</label>
64 <textarea id="generatedUrl" readonly></textarea>
65 </div>
66 <button type="button" onclick="sendGetRequest(this)">发送 GET 请求</button>
67 <h2>响应:</h2>
68 <pre id="response"></pre>
69 <script>
70 // MD5加密函数
71 function md5(value) {
72 return CryptoJS.MD5(value).toString();
73 }
74
75 // 双重MD5加密函数
76 function doubleMd5(value) {
77 return md5(md5(value));
78 }
79
80 // 转换AppKey为双重MD5值
81 function convertAppKey() {
82 const appKeyInput = document.getElementById('getAppKey');
83 const appKey = appKeyInput.value;
84 const appKeyHashed = doubleMd5(appKey);
85 appKeyInput.value = appKeyHashed;
86 generateSigningString(appKeyHashed);
87 }
88
89 // 生成待签名字符串
90 function generateSigningString(appKeyHashed = null) {
91 const appid = document.getElementById('getAppID').value;
92 const time = document.getElementById('getTime').value;
93 const token = document.getElementById('getToken').value;
94 const status = document.getElementById('getStatus').value;
95 const o = document.getElementById('getO').value;
96
97 const params = {
98 AppID: appid,
99 Time: time,
100 token: token,
101 status: status,
102 o: o
103 };
104
105 // 按参数名从小到大排序并生成KV字符串
106 const sortedKeys = Object.keys(params).sort();
107 const signingString = sortedKeys.map(key => `${key}=${encodeURIComponent(params[key])}`).join('&');
108
109 // 将KV字符串与AppKey连接
110 const finalSigningString = `${signingString}&${appKeyHashed}`;
111
112 // 更新待签名字符串文本域
113 document.getElementById('signingString').value = finalSigningString;
114 }
115
116 // 生成签名
117 function generateSignature() {
118 const appkey = document.getElementById('getAppKey').value;
119 const signingString = document.getElementById('signingString').value;
120
121 // 对最终签名字符串进行MD5加密
122 const signature = md5(signingString);
123 document.getElementById('signature').value = signature;
124
125 // 生成完整的请求URL,不包括AppKey
126 const url = document.getElementById('getUrl').value;
127 const apiPath = document.getElementById('getApiPath').value;
128 const baseSigningString = signingString.split(`&${appkey}`).shift(); // 移除AppKey部分
129 const fullUrl = `${url}${apiPath}?${baseSigningString}&Signature=${signature}`;
130 document.getElementById('generatedUrl').value = fullUrl;
131 }
132
133 // 发送GET请求
134 async function sendGetRequest(button) {
135 // 禁用按钮
136 button.disabled = true;
137
138 const fullUrl = document.getElementById('generatedUrl').value;
139
140 try {
141 const response = await fetch(fullUrl);
142 const data = await response.json();
143 document.getElementById('response').textContent = JSON.stringify(data, null, 2);
144 } catch (error) {
145 console.error('GET 请求错误', error);
146 document.getElementById('response').textContent = '请求失败,请检查控制台日志。';
147 } finally {
148 // 启用按钮
149 button.disabled = false;
150 }
151 }
152
153 // 获取当前时间戳并设置到输入框
154 function setCurrentTimestamp() {
155 const currentTimestamp = Math.floor(Date.now() / 1000);
156 document.getElementById('getTime').value = currentTimestamp;
157 }
158
159 // 输入参数变更时重新生成签名字符串
160 document.querySelectorAll('input').forEach(input => {
161 input.addEventListener('input', () => generateSigningString(document.getElementById('getAppKey').value));
162 });
163
164 // 设置服务器url
165 const baseUrl = `${window.location.protocol}//${window.location.host}`;
166 document.getElementById('getUrl').value = baseUrl;
167
168 setCurrentTimestamp(); // 初始设置当前时间戳
169 generateSigningString(); // 初始生成签名字符串
170 </script>
171</body>
172</html>
tr069-api-post.html
HTTP POST 方式请求:
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>API 测试客户端</title>
6 <style>
7 body {
8 font-family: Arial, sans-serif;
9 }
10 form {
11 margin-bottom: 20px;
12 }
13 label {
14 display: block;
15 margin-top: 10px;
16 }
17 input, textarea, button {
18 display: block;
19 margin-top: 5px;
20 width: 100%;
21 max-width: 700px;
22 font-size: 16px;
23 padding: 10px;
24 }
25 textarea {
26 height: 150px;
27 }
28 .container {
29 margin-bottom: 20px;
30 }
31 </style>
32 <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
33</head>
34<body>
35 <h1>TR069 API 测试客户端 - POST 方式</h1>
36 <div class="container">
37 <label for="postUrl">POST 请求 URL:</label>
38 <input type="text" id="postUrl" name="postUrl" value="" required>
39 <label for="postApiPath">API 路径:</label>
40 <input type="text" id="postApiPath" name="postApiPath" value="/api/post_tr069" required>
41 <label for="postAppID">AppID:</label>
42 <input type="text" id="postAppID" name="postAppID" value="apitest" required>
43 <label for="postAppKey">AppKey:</label>
44 <input type="text" id="postAppKey" name="postAppKey" value="admin@123" required>
45 <button type="button" onclick="convertAppKey()">转换</button>
46 <label for="postTime">时间戳:</label>
47 <input type="text" id="postTime" name="postTime" value="1621500119" required>
48 <label for="postToken">Token:</label>
49 <input type="text" id="postToken" name="postToken" value="123456" required>
50 <label for="postO">动作参数:</label>
51 <input type="text" id="postO" name="postO" value="enable_telnet" required>
52 <label for="postTarget">Target 目标:</label>
53 <input type="text" id="postTarget" name="postTarget" value="00259E-4857544317EDA19C" required>
54 </div>
55 <div class="container">
56 <label for="signingString">待签名的 URL 字符串:</label>
57 <textarea id="signingString" rows="4" readonly></textarea>
58 <button type="button" onclick="generateSignature()">生成签名</button>
59 <label for="signature">签名:</label>
60 <input type="text" id="signature" readonly>
61 </div>
62 <div class="container">
63 <label for="generatedCurl">生成的 cURL 命令:</label>
64 <textarea id="generatedCurl" readonly></textarea>
65 </div>
66 <button type="button" onclick="sendPostRequest(this)">发送 POST 请求</button>
67 <h2>响应:</h2>
68 <pre id="response"></pre>
69 <script>
70 // MD5加密函数
71 function md5(value) {
72 return CryptoJS.MD5(value).toString();
73 }
74
75 // 双重MD5加密函数
76 function doubleMd5(value) {
77 return md5(md5(value));
78 }
79
80 // 转换AppKey为双重MD5值
81 function convertAppKey() {
82 const appKeyInput = document.getElementById('postAppKey');
83 const appKey = appKeyInput.value;
84 const appKeyHashed = doubleMd5(appKey);
85 appKeyInput.value = appKeyHashed;
86 generateSigningString(appKeyHashed);
87 }
88
89 // 生成待签名字符串
90 function generateSigningString(appKeyHashed = null) {
91 const appid = document.getElementById('postAppID').value;
92 const time = document.getElementById('postTime').value;
93 const token = document.getElementById('postToken').value;
94 const o = document.getElementById('postO').value;
95 const target = document.getElementById('postTarget').value;
96
97 const params = {
98 AppID: appid,
99 Time: time,
100 token: token,
101 o: o,
102 target: target
103 };
104
105 // 按参数名从小到大排序并生成KV字符串
106 const sortedKeys = Object.keys(params).sort();
107 const signingString = sortedKeys.map(key => `${key}=${encodeURIComponent(params[key])}`).join('&');
108
109 // 将KV字符串与AppKey连接
110 const finalSigningString = `${signingString}&${appKeyHashed}`;
111
112 // 更新待签名字符串文本域
113 document.getElementById('signingString').value = finalSigningString;
114 }
115
116 // 生成签名
117 function generateSignature() {
118 const appkey = document.getElementById('postAppKey').value;
119 const signingString = document.getElementById('signingString').value;
120
121 // 对最终签名字符串进行MD5加密
122 const signature = md5(signingString);
123 document.getElementById('signature').value = signature;
124
125 // 生成cURL命令
126 generateCurlCommand();
127 }
128
129 // 生成cURL命令
130 function generateCurlCommand() {
131 const url = document.getElementById('postUrl').value;
132 const apiPath = document.getElementById('postApiPath').value;
133 const fullUrl = `${url}${apiPath}`;
134 const appid = document.getElementById('postAppID').value;
135 const time = document.getElementById('postTime').value;
136 const token = document.getElementById('postToken').value;
137 const o = document.getElementById('postO').value;
138 const target = document.getElementById('postTarget').value;
139 const signature = document.getElementById('signature').value;
140
141 const curlCommand = `curl -X POST ${fullUrl} -H "Content-Type: application/x-www-form-urlencoded" -d '` +
142 `AppID=${appid}&Time=${time}&token=${token}&o=${o}&target=${target}&Signature=${signature}'`;
143 document.getElementById('generatedCurl').value = curlCommand;
144 }
145
146 // 发送POST请求
147 async function sendPostRequest(button) {
148 // 禁用按钮
149 button.disabled = true;
150
151 const url = document.getElementById('postUrl').value;
152 const apiPath = document.getElementById('postApiPath').value;
153 const fullUrl = `${url}${apiPath}`;
154 const appid = document.getElementById('postAppID').value;
155 const time = document.getElementById('postTime').value;
156 const token = document.getElementById('postToken').value;
157 const o = document.getElementById('postO').value;
158 const target = document.getElementById('postTarget').value;
159 const signature = document.getElementById('signature').value;
160
161 // 构建POST参数
162 const body = new URLSearchParams();
163 body.append('AppID', appid);
164 body.append('Time', time);
165 body.append('token', token);
166 body.append('o', o);
167 body.append('target', target);
168 body.append('Signature', signature);
169
170 // 提交POST请求
171 try {
172 const response = await fetch(fullUrl, {
173 method: 'POST',
174 headers: {
175 'Content-Type': 'application/x-www-form-urlencoded'
176 },
177 body: body.toString()
178 });
179 const data = await response.json();
180 document.getElementById('response').textContent = JSON.stringify(data, null, 2);
181 generateCurlCommand(); // 生成cURL命令
182 } catch (error) {
183 console.error('POST 请求错误', error);
184 document.getElementById('response').textContent = '请求失败,请检查控制台日志。';
185 } finally {
186 // 启用按钮
187 button.disabled = false;
188 }
189 }
190
191 // 获取当前时间戳并设置到输入框
192 function setCurrentTimestamp() {
193 const currentTimestamp = Math.floor(Date.now() / 1000);
194 document.getElementById('postTime').value = currentTimestamp;
195 }
196
197 // 输入参数变更时重新生成签名字符串
198 document.querySelectorAll('input').forEach(input => {
199 input.addEventListener('input', () => generateSigningString(document.getElementById('postAppKey').value));
200 });
201
202 // 设置服务器url
203 const baseUrl = `${window.location.protocol}//${window.location.host}`;
204 document.getElementById('postUrl').value = baseUrl;
205
206 setCurrentTimestamp(); // 初始设置当前时间戳
207 generateSigningString(); // 初始生成签名字符串
208 </script>
209</body>
210</html>