---
url: https://docs.ogmabox.com/zh/plugins/frontend-sdk.md
description: Ogma 前端插件 API 参考，涵盖 iframe 集成、桥接调用、UI 面板、命令和宿主通信。
---

# 插件前端 SDK 参考 {#plugin-frontend-sdk-reference}

插件前端代码在沙箱 iframe 内运行。本文档提供底层参考。更高层次的介绍请参阅 [README.md](./README.md)。

***

## 安全模型 {#security-model}

| 属性 | 值 |
|----------|-------|
| iframe 沙箱 | 仅允许 `allow-scripts`（不包含 `allow-same-origin`） |
| CSP `script-src` | 由 nonce 控制；仅加载入口脚本 |
| CSP `connect-src` | `'self'`：插件可向 `/plugins/{id}/api/*` 发送 POST 请求，并轮询 `/plugins/{id}/events/poll` |
| CSP `default-src` | `'none'` |
| 父级 DOM 访问 | 被阻止（不包含 `allow-same-origin`） |
| Ogma 会话 Cookie | 插件无法访问 |
| 跨插件通信 | 不可用 |

数据桥接调用的每个请求都会在服务器端进行授权；显示和导航操作由宿主 UI 处理。权限选项卡中显示的权限缓存仅用于展示，不控制数据访问。

***

## 桥接协议 {#bridge-protocol}

插件 JS 通过 `postMessage` 与 Ogma 宿主通信。宿主位于 `PluginsView.vue` 中，负责处理 `bridge_request` 消息。

### 请求封装 {#request-envelope}

```ts
interface BridgeRequest {
  type: 'bridge_request'
  sessionId: string     // nonce assigned when the bridge is set up; prevents stale messages
  requestId: string     // caller-generated correlation id (max 128 chars)
  command: string       // e.g. "ogma.requests.get"
  payload?: unknown     // command-specific input
}
```

消息总大小上限：65 536 字节。

### 响应封装 {#response-envelope}

```ts
interface BridgeResponse {
  type: 'bridge_response'
  requestId: string
  ok: boolean
  result?: unknown
  error?: string
  code?: string
}
```

### 使用 SDK（推荐） {#using-the-sdk-recommended}

不要手动发送原始 `postMessage` 桥接请求。请使用全局对象 `ogmaSDK`：

```js
ogmaSDK.ready(function(sdk) {
  sdk.meta.get().then(function(meta) {
    sdk.log.info("running as " + meta.pluginId);
  });
});
```

SDK 封装所有桥接通信，并处理请求关联、sessionId 管理和 Promise 的完成处理。

***

## 命令参考 {#command-reference}

### `ogma.meta.get` {#ogma-meta-get}

无需载荷。

返回 `{ pluginId, packageId, name, version, ogmaVersion }`。

### `ogma.requests.get` {#ogma-requests-get}

载荷：`{ id: string }`

返回经过字段投影的 HTTP 条目。字段：`id`、`method`、`host`、`port`、`path`、`query`、`req_len`、`resp_status`、`resp_len`、`roundtrip_ms`、`created_at`。此投影不包含头部或消息体字节。

需要：`read_http_history`（自动授予）。

### `ogma.requests.getRaw` {#ogma-requests-getraw}

载荷：`{ id: string }`。通过 `sdk.requests.getRaw(id)` 调用。

返回 `requestBodyBase64`、`responseBodyBase64`、解码后的长度（`requestBodyLength`、`responseBodyLength`）、`requestBodyTruncated`、`responseBodyTruncated` 和 `maxBodyBytes`。尽管名称包含 Raw，此操作返回的是消息体字节，而非完整的原始 HTTP 消息。支持的内容编码会在投影前解码。每个消息体上限为 256 KiB；处理完整资源前，请检查截断标志。

需要：`read_http_history`（自动授予）。

### `ogma.requests.search` {#ogma-requests-search}

载荷：`{ limit?: number, offset?: number, query?: string }`

`query` 支持 HTTPQL 过滤表达式。`limit` 上限：20。返回 `{ items: [...], total: number, limit: number, offset: number }`。

需要：`read_http_history`（自动授予）。

### `ogma.findings.list` {#ogma-findings-list}

载荷：`{ limit?: number, offset?: number }`

返回 `{ items: [...], total: number, limit: number, offset: number }`，每页最多 20 个安全发现。条目为摘要；字段包括 `id`、`title`、`severity`、`status`、`reporter`、`tags` 和 `created_at`。

需要：`read_findings`（自动授予）。

### `ogma.scope.getActive` {#ogma-scope-getactive}

无载荷。返回当前测试范围预设或 `null`。

需要：`read_scope`（自动授予）。

### `ogma.projects.getCurrent` {#ogma-projects-getcurrent}

无载荷。返回 `{ id, name, status }` 或 `null`。

需要：`read_projects`（自动授予）。

### `ogma.log` {#ogma-log}

载荷：`{ message: string }`

写入插件日志缓冲区。

### `ogma.ui.resize` {#ogma-ui-resize}

载荷：`{ height: number }`（上限 2000）

请求宿主设置 iframe 高度。

### `ogma.ui.sidebar.registerItem` {#ogma-ui-sidebar-registeritem}

载荷：`{ name: string, path: string }`（name 最多 64 个字符，path 最多 256 个字符）

注册插件面板内的导航。每个插件最多 20 个条目。使用 `sdk.navigation.addPage(path, { title, body })` 注册对应的页面内容；选择条目时会在 iframe 内显示该页面，而非创建新的 Ogma 顶层工作区路由。

### `ogma.backend.call` {#ogma-backend-call}

载荷：`{ method: string, args: unknown[] }`

调用通过 `sdk.api.register(method, fn)` 注册的后端 RPC 处理函数。方法名长度上限为 64 个字符。

返回后端处理函数的返回值，经过 JSON 序列化。

### `ogma.backend.onEvent` {#ogma-backend-onevent}

载荷：无需载荷。

仅确认该操作。实际获取事件请使用 `ogma.events.poll`。

### `ogma.events.poll` {#ogma-events-poll}

载荷：`{ since: number }`（上次轮询的索引；从 0 开始）

返回 `{ events: [{ event: string, args: unknown[] }], next_since: number }`。

### `ogma.navigation.addPage` {#ogma-navigation-addpage}

载荷：`{ path: string, title?: string }`

桥接会确认页面路径。注入的 SDK 还支持将 `{ body: HTMLElement }` 作为 `sdk.navigation.addPage(path, options)` 的选项，将内容附加到 iframe 内，并在宿主选择匹配的侧边栏条目时切换页面可见性。DOM 节点保留在本地，不会通过桥接序列化传输。

### `ogma.window.showToast` {#ogma-window-showtoast}

载荷：`{ message: string, variant?: "info"|"success"|"warning"|"error", duration?: number }`

在插件面板中显示提示通知。持续时间单位为毫秒（上限 10000，默认 3000）。

### `ogma.commands.register` {#ogma-commands-register}

载荷：`{ id: string, name: string }`

在宿主命令存储中注册插件命令。宿主执行命令时，会向 iframe 发回包含 `commandId` 和上下文的 `plugin_command` 消息；插件必须提供对应的回调。仅注册不会执行命令。

### `ogma.menu.registerItem` {#ogma-menu-registeritem}

载荷：`{ type?: "Request" | "RequestRow" | "Response", commandId: string, label?: string }`

注册与插件命令关联的上下文菜单条目。请先注册命令。标签默认使用命令注册名称，若无则使用其 ID；省略 `type` 时默认为 `Request`。宿主桥接不会使用 `leadingIcon`。

### 主题辅助函数 {#theme-helpers}

注入的 SDK 还提供 `sdk.theme.get()` 和 `sdk.theme.onChange(callback)`。它们读取 iframe 主题并订阅宿主主题更新，无需单独的数据桥接命令。使用这些函数可使插件 UI 与 Ogma 的浅色/深色外观保持一致。

***

## 错误代码 {#error-codes}

| 代码 | 含义 |
|------|---------|
| `PERMISSION_DENIED` | 插件缺少所需权限。 |
| `PLUGIN_DISABLED` | 插件当前未启用。 |
| `UNKNOWN_COMMAND` | 命令不在支持列表中。 |
| `INVALID_PAYLOAD` | 必需的载荷字段缺失或类型错误。 |
| `NOT_FOUND` | 请求的资源不存在。 |
| `LIMIT_EXCEEDED` | 已达到每个插件的数量限制（例如侧边栏条目）。 |
| `SERVER_ERROR` | 内部错误。请检查插件日志。 |

***

## 支持的命令列表 {#supported-commands-list}

`ogma.meta.get`, `ogma.log`, `ogma.ui.resize`, `ogma.ui.sidebar.registerItem`, `ogma.requests.get`, `ogma.requests.getRaw`, `ogma.requests.search`, `ogma.findings.list`, `ogma.scope.getActive`, `ogma.projects.getCurrent`, `ogma.backend.call`, `ogma.backend.onEvent`, `ogma.events.poll`, `ogma.navigation.addPage`, `ogma.window.showToast`, `ogma.commands.register`, `ogma.menu.registerItem`.
