Files
opsxapi/homepage/dist/docs/server-api/index.html
T
logan f6f61b35d8 文档去源码化:公开文档不再引导 git clone / run.sh(商业软件口径)
- 02-快速开始 整篇重写为最终用户视角:官网/微信群获取安装包 → 安装即用 →
  30 秒首请求 → 切换环境 → 试用与授权指引;删除环境要求表/克隆启动/命令表
- 01-介绍「开箱即用」改为安装即用口径;08-WebSocket 隧道说明改为随应用自动运行;
  19-FAQ CORS 排查项去掉 curl/run.sh;18-服务端部署建议改为私有化发行包交付
  (单二进制+静态资源,不依赖源码与构建工具链)
- 重建后 quickstart/落地页 git clone、run.sh、npm、cargo 残留均为 0;五页零断链
2026-10-16 12:19:30 +08:00

276 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>服务端 API 参考 · OpsxAPI 文档</title>
<meta name="description" content="OpsxAPI 接口工作台用户文档 — HTTP、GraphQL、WebSocket、SSE、Socket.IO、MQTT 一站式调试,支持 OpenAPI/Postman/cURL 等格式导入导出。">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='7' fill='%232563eb'/%3E%3Ctext x='16' y='22' font-size='18' font-weight='bold' fill='%23fff' text-anchor='middle' font-family='sans-serif'%3EO%3C/text%3E%3C/svg%3E">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%2264%22%20y2%3D%2264%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%232563EB%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%2306B6D4%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%2264%22%20height%3D%2264%22%20rx%3D%2214%22%20fill%3D%22url%28%23g%29%22%2F%3E%3Cg%20stroke%3D%22%23fff%22%20stroke-width%3D%225%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M17%2025h26%22%2F%3E%3Cpath%20d%3D%22M37%2019l6%206-6%206%22%2F%3E%3Cpath%20d%3D%22M47%2039H21%22%2F%3E%3Cpath%20d%3D%22M27%2033l-6%206%206%206%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E">
<link rel="stylesheet" href="/docs/assets/docs.css">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
<symbol id="i-menu" viewBox="0 0 24 24"><path d="M4 5h16" /> <path d="M4 12h16" /> <path d="M4 19h16" /></symbol>
<symbol id="i-printer" viewBox="0 0 24 24"><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2" /> <path d="M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6" /> <rect x="6" y="14" width="12" height="8" rx="1" /></symbol>
<symbol id="i-thumbs-up" viewBox="0 0 24 24"><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" /> <path d="M7 10v12" /></symbol>
<symbol id="i-thumbs-down" viewBox="0 0 24 24"><path d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z" /> <path d="M17 14V2" /></symbol>
<symbol id="i-rocket" viewBox="0 0 24 24"><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5" /> <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09" /> <path d="M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z" /> <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05" /></symbol>
<symbol id="i-shield-check" viewBox="0 0 24 24"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" /> <path d="m9 12 2 2 4-4" /></symbol>
<symbol id="i-arrow-left-right" viewBox="0 0 24 24"><path d="M8 3 4 7l4 4" /> <path d="M4 7h16" /> <path d="m16 21 4-4-4-4" /> <path d="M20 17H4" /></symbol>
<symbol id="i-plug-zap" viewBox="0 0 24 24"><path d="M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z" /> <path d="m2 22 3-3" /> <path d="M7.5 13.5 10 11" /> <path d="M10.5 16.5 13 14" /> <path d="m18 3-4 4h6l-4 4" /></symbol>
<symbol id="i-package" viewBox="0 0 24 24"><path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z" /> <path d="M12 22V12" /> <polyline points="3.29 7 12 12 20.71 7" /> <path d="m7.5 4.27 9 5.15" /></symbol>
<symbol id="i-folder-tree" viewBox="0 0 24 24"><path d="M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z" /> <path d="M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z" /> <path d="M3 5a2 2 0 0 0 2 2h3" /> <path d="M3 3v13a2 2 0 0 0 2 2h3" /></symbol>
<symbol id="i-globe" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" /> <path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" /> <path d="M2 12h20" /></symbol>
<symbol id="i-hexagon" viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" /></symbol>
<symbol id="i-zap" viewBox="0 0 24 24"><path d="M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z" /></symbol>
<symbol id="i-radio" viewBox="0 0 24 24"><path d="M16.247 7.761a6 6 0 0 1 0 8.478" /> <path d="M19.075 4.933a10 10 0 0 1 0 14.134" /> <path d="M4.925 19.067a10 10 0 0 1 0-14.134" /> <path d="M7.753 16.239a6 6 0 0 1 0-8.478" /> <circle cx="12" cy="12" r="2" /></symbol>
<symbol id="i-mailbox" viewBox="0 0 24 24"><path d="M22 17a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9.5C2 7 4 5 6.5 5H18c2.2 0 4 1.8 4 4v8Z" /> <polyline points="15,9 18,9 18,11" /> <path d="M6.5 5C9 5 11 7 11 9.5V17a2 2 0 0 1-2 2" /> <line x1="6" x2="7" y1="10" y2="10" /></symbol>
<symbol id="i-code" viewBox="0 0 24 24"><path d="m16 18 6-6-6-6" /> <path d="m8 6-6 6 6 6" /></symbol>
<symbol id="i-book-open" viewBox="0 0 24 24"><path d="M12 5v16" /> <path d="M20.001 19A2 2 0 0022 17V5a2 2 0 00-1.999-2L16 3.002A5 5 0 0012 5a5 5 0 00-4-2H4a2 2 0 00-2 2v12a2 2 0 001.999 2H8a5 5 0 014 2 5 5 0 014-2z" /></symbol>
<symbol id="i-sprout" viewBox="0 0 24 24"><path d="M14 9.536V7a4 4 0 0 1 4-4h1.5a.5.5 0 0 1 .5.5V5a4 4 0 0 1-4 4 4 4 0 0 0-4 4c0 2 1 3 1 5a5 5 0 0 1-1 3" /> <path d="M4 9a5 5 0 0 1 8 4 5 5 0 0 1-8-4" /> <path d="M5 21h14" /></symbol>
<symbol id="i-graduation-cap" viewBox="0 0 24 24"><path d="M21.42 10.922a1 1 0 0 0-.019-1.838L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.832l8.57 3.908a2 2 0 0 0 1.66 0z" /> <path d="M22 10v6" /> <path d="M6 12.5V16a6 3 0 0 0 12 0v-3.5" /></symbol>
<symbol id="i-credit-card" viewBox="0 0 24 24"><rect width="20" height="14" x="2" y="5" rx="2" /> <line x1="2" x2="22" y1="10" y2="10" /> <path d="M6 14h2" /></symbol>
<symbol id="i-megaphone" viewBox="0 0 24 24"><path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z" /> <path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14" /> <path d="M8 6v8" /></symbol>
<symbol id="i-download" viewBox="0 0 24 24"><path d="M12 15V3" /> <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /> <path d="m7 10 5 5 5-5" /></symbol>
<symbol id="i-upload" viewBox="0 0 24 24"><path d="M12 3v12" /> <path d="m17 8-5-5-5 5" /> <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /></symbol>
<symbol id="i-library" viewBox="0 0 24 24"><path d="m16 6 4 14" /> <path d="M12 6v14" /> <path d="M8 8v12" /> <path d="M4 4v16" /></symbol>
<symbol id="i-settings" viewBox="0 0 24 24"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /> <circle cx="12" cy="12" r="3" /></symbol>
<symbol id="i-search" viewBox="0 0 24 24"><path d="m21 21-4.34-4.34" /> <circle cx="11" cy="11" r="8" /></symbol>
</svg>
<header class="topbar">
<div class="topbar-inner">
<button class="menu-btn" id="menu-btn" aria-label="打开导航"><svg class="i"><use href="#i-menu"/></svg></button>
<a class="brand" href="/docs">
<span class="brand-logo"><svg width="28" height="28" viewBox="0 0 64 64" aria-label="OpsxAPI"><defs><linearGradient id="lg-docs" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2563EB"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-docs)"/><g stroke="#fff" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none"><path d="M17 25h26"/><path d="M37 19l6 6-6 6"/><path d="M47 39H21"/><path d="M27 33l-6 6 6 6"/></g></svg></span>
<span class="brand-name">OpsxAPI <em>文档</em></span>
</a>
<span class="ver-badge">v1.0</span>
<div class="search">
<input id="search-input" type="search" placeholder="搜索文档…" autocomplete="off" spellcheck="false">
<div class="search-panel" id="search-panel" hidden></div>
</div>
<nav class="top-links">
<a href="/home">官网</a>
<a href="/" target="_blank" rel="noopener">打开工作台 ↗</a>
</nav>
</div>
</header>
<div class="layout" id="layout">
<aside class="sidebar" id="sidebar">
<div class="nav-group">
<div class="nav-group-title">开始使用</div>
<a class="nav-link" href="/docs/intro">产品介绍</a>
<a class="nav-link" href="/docs/quickstart">快速开始</a>
<a class="nav-link" href="/docs/interface">界面导览</a>
</div>
<div class="nav-group">
<div class="nav-group-title">请求调试</div>
<a class="nav-link" href="/docs/http">发送 HTTP 请求</a>
<a class="nav-link" href="/docs/auth">接口鉴权</a>
<a class="nav-link" href="/docs/env">环境与变量</a>
<a class="nav-link" href="/docs/graphql">GraphQL</a>
<a class="nav-link" href="/docs/websocket">WebSocket</a>
<a class="nav-link" href="/docs/sse">SSE 事件流</a>
<a class="nav-link" href="/docs/socketio">Socket.IO</a>
<a class="nav-link" href="/docs/mqtt">MQTT</a>
</div>
<div class="nav-group">
<div class="nav-group-title">数据管理</div>
<a class="nav-link" href="/docs/import">数据导入</a>
<a class="nav-link" href="/docs/export">导出与代码生成</a>
<a class="nav-link" href="/docs/mock">Mock 数据</a>
<a class="nav-link" href="/docs/manage">集合与历史</a>
</div>
<div class="nav-group">
<div class="nav-group-title">自动化测试与 AI</div>
<a class="nav-link" href="/docs/testing">自动化测试</a>
<a class="nav-link" href="/docs/ai">AI 助手</a>
</div>
<div class="nav-group">
<div class="nav-group-title">账号与团队</div>
<a class="nav-link" href="/docs/account">账号与团队</a>
</div>
<div class="nav-group">
<div class="nav-group-title">参考</div>
<a class="nav-link" href="/docs/license">授权与激活</a>
<a class="nav-link active" href="/docs/server-api">服务端 API 参考</a>
<a class="nav-link" href="/docs/faq">常见问题</a>
</div>
<div class="sidebar-foot">© 2026 OpsxAPI · 本地优先的接口工作台</div>
</aside>
<main class="content">
<div class="breadcrumb">文档 <span>/</span> 参考 <span>/</span> 服务端 API 参考</div>
<h1 class="page-title">服务端 API 参考</h1>
<div class="page-meta">更新于 2026-09-17</div>
<article class="md">
<p>本地服务(Gin)默认监听 <code>:8787</code>,可用环境变量 <code>OPSXAPI_ADDR</code> 修改。所有端点仅监听本机回环,供 Web UI 与桌面端调用。</p>
<h2 id="sec-1">端点总览</h2>
<table>
<thead>
<tr>
<th>方法</th>
<th>路径</th>
<th>用途</th>
</tr>
</thead>
<tbody>
<tr>
<td>GET</td>
<td><code>/health</code></td>
<td>健康检查</td>
</tr>
<tr>
<td>POST</td>
<td><code>/v1/proxy/http</code></td>
<td>HTTP 代理(全方法、自定义头、超时)</td>
</tr>
<tr>
<td>POST</td>
<td><code>/v1/proxy/http/stream</code></td>
<td>NDJSON 流式代理(SSE / chunked 透传)</td>
</tr>
<tr>
<td>POST</td>
<td><code>/v1/proxy/ws/connect</code></td>
<td>建立到目标 WS 的隧道会话</td>
</tr>
<tr>
<td>GET</td>
<td><code>/v1/proxy/ws/attach</code></td>
<td>浏览器 attach 到隧道会话(双向桥接)</td>
</tr>
<tr>
<td>POST</td>
<td><code>/v1/proxy/ws/close</code></td>
<td>关闭隧道会话</td>
</tr>
<tr>
<td>GET</td>
<td><code>/docs</code></td>
<td>本文档站</td>
</tr>
</tbody>
</table>
<h2 id="sec-2">HTTP 代理</h2>
<pre><code class="language-bash">curl -s -X POST http://127.0.0.1:8787/v1/proxy/http \
-H 'Content-Type: application/json' \
-d '{&quot;method&quot;:&quot;GET&quot;,&quot;url&quot;:&quot;https://httpbin.org/get&quot;,&quot;headers&quot;:{}}'
</code></pre>
<p>响应:</p>
<pre><code class="language-json">{
&quot;status&quot;: 200,
&quot;headers&quot;: { &quot;content-type&quot;: &quot;application/json&quot; },
&quot;body&quot;: &quot;{ ... }&quot;,
&quot;timeMs&quot;: 320,
&quot;size&quot;: 274
}
</code></pre>
<p>请求体 <code>body.mode</code> 支持 <code>json</code> / <code>xml</code> / <code>text</code> / <code>html</code> / <code>urlencoded</code> / <code>form-data</code>,<code>raw</code> 为原始报文;<code>timeoutMs</code> 可选。</p>
<h2 id="sec-3">流式代理</h2>
<p>请求体与 HTTP 代理一致,响应为 NDJSON 事件流:</p>
<pre><code class="language-text">{&quot;type&quot;:&quot;meta&quot;,&quot;status&quot;:200,&quot;headers&quot;:{...}}
{&quot;type&quot;:&quot;chunk&quot;,&quot;data&quot;:&quot;&lt;base64&gt;&quot;,&quot;size&quot;:1024}
{&quot;type&quot;:&quot;end&quot;,&quot;timeMs&quot;:1200,&quot;size&quot;:8192}
</code></pre>
<h2 id="sec-4">WebSocket 隧道</h2>
<pre><code class="language-bash"># 1. 建立会话(可带自定义 Header)
curl -s -X POST http://127.0.0.1:8787/v1/proxy/ws/connect \
-H 'Content-Type: application/json' \
-d '{&quot;url&quot;:&quot;wss://echo.example.com&quot;,&quot;headers&quot;:{&quot;Authorization&quot;:&quot;Bearer t&quot;}}'
# → {&quot;sessionId&quot;:&quot;...&quot;}
# 2. 浏览器 / 客户端 attach(普通 WebSocket)
# ws://127.0.0.1:8787/v1/proxy/ws/attach?sessionId=...
# 3. 关闭
curl -s -X POST http://127.0.0.1:8787/v1/proxy/ws/close \
-H 'Content-Type: application/json' -d '{&quot;sessionId&quot;:&quot;...&quot;}'
</code></pre>
<p>attach 后第一条消息为控制帧 <code>{&quot;type&quot;:&quot;open&quot;}</code>;此后浏览器与目标服务器双向透传。</p>
<h2 id="sec-5">安全边界</h2>
<ul>
<li>仅允许 <code>http/https</code>(代理)与 <code>ws/wss</code>(隧道)目标。</li>
<li>拒绝云元数据地址(169.254.169.254 等)防 SSRF。</li>
<li>单响应上限 10 MiB;隧道会话 10 分钟无活动自动回收。</li>
</ul>
<h2 id="sec-6">部署建议</h2>
<ul>
<li>私有化交付随授权提供发行包(<code>opsxapi-server</code> 单二进制 + 官网静态资源),解压即用,不依赖源码与构建工具链;</li>
<li>生产环境建议置于内网,并按需增加鉴权反向代理;数据目录(SQLite)做好备份策略。</li>
</ul>
</article>
<div class="pn-nav">
<a class="pn prev" href="/docs/license"><span class="pn-label">← 上一页</span><span class="pn-title">授权与激活</span></a>
<a class="pn next" href="/docs/faq"><span class="pn-label">下一页 →</span><span class="pn-title">常见问题</span></a>
</div>
<div class="feedback" id="feedback">
<span class="feedback-q">本页内容是否对您有帮助?</span>
<button class="fb-btn" data-v="yes"><svg class="i"><use href="#i-thumbs-up"/></svg> 有帮助</button>
<button class="fb-btn" data-v="no"><svg class="i"><use href="#i-thumbs-down"/></svg> 没有帮助</button>
<span class="fb-thanks" id="fb-thanks" hidden>感谢您的反馈!</span>
</div>
</main>
<aside class="toc">
<div class="toc-title">本页目录</div>
<nav class="toc-nav">
<a class="toc-l2" href="#sec-1">端点总览</a>
<a class="toc-l2" href="#sec-2">HTTP 代理</a>
<a class="toc-l2" href="#sec-3">流式代理</a>
<a class="toc-l2" href="#sec-4">WebSocket 隧道</a>
<a class="toc-l2" href="#sec-5">安全边界</a>
<a class="toc-l2" href="#sec-6">部署建议</a>
</nav>
<button class="print-btn" id="print-btn"><svg class="i"><use href="#i-printer"/></svg> 打印 / 导出 PDF</button>
</aside>
</div>
<script src="/docs/assets/docs.js" defer></script>
</body>
</html>