跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI大前端

A2UI 技术原理深度解析:AI Agent 如何安全生成富交互 UI

Google 开源的 A2UI 协议通过声明式 JSON 描述 UI,解决了 AI Agent 跨信任边界生成富交互界面的安全问题。其核心采用三层解耦架构(组件树、数据模型、组件目录),利用邻接表模型替代嵌套树,降低 LLM 生成难度并支持流式传输。协议定义了 surfaceUpdate、dataModelUpdate 等消息类型,实现 UI 结构与数据的分离。安全机制依赖客户端预定义组件白名单及目录协商,LLM 仅能输出符合 Schema 约束的数据,无法执行恶意代码。业务逻辑由 Agent 通过工具或子代理处理,确保渲染层纯净可控。

晚风告白发布于 2026/4/5更新于 2026/9/1068 浏览

本文深入解析 Google 开源的 A2UI 协议,探讨其核心架构、数据流设计以及为何它是 LLM 生成 UI 的最佳实践。

一、A2UI 是什么?

A2UI (Agent-to-User Interface) 是 Google 于 2025 年开源的声明式 UI 协议。它解决了一个核心问题:

如何让 AI Agent 安全地跨信任边界发送富交互 UI?

传统的 Agent 交互往往是纯文本对话,效率低下。而直接让 LLM 生成 HTML/JS 代码又存在严重的安全风险。A2UI 提供了一个中间方案:Agent 发送声明式 JSON 描述 UI 意图,客户端使用自己的原生组件渲染。

安全性:像数据一样安全 表达力:像代码一样丰富 

二、核心设计理念

2.1 三层解耦架构

A2UI 的核心哲学是将三个关键元素解耦:

┌─────────────────────────────────────────────────────────┐
│ A2UI 三层架构                                           │
├─────────────────────────────────────────────────────────┤
│ 1. 组件树 (Structure) - Agent 提供的抽象 UI 结构         │
│ 2. 数据模型 (State) - 动态填充 UI 的应用状态             │
│ 3. 组件目录 (Catalog) - 客户端定义的可信组件映射        │
└─────────────────────────────────────────────────────────┘

这种设计带来的好处:

  • 安全性:Agent 只能使用客户端预定义的组件,无法注入恶意代码
  • 灵活性:同一份 UI 描述可在不同框架(Angular/Flutter/React)上渲染
  • 高效性:数据变更无需重发整个 UI 结构
2.2 邻接表模型 vs 嵌套树

这是 A2UI 最精妙的设计之一。传统 UI 描述使用嵌套 JSON 树:

//传统嵌套结构 - LLM 难以一次性生成正确
{
"type":"Column",
"children":[{"type":"Text","text":"Hello"},{"type":"Row","children":[{"type":"Button","child":{"type":"Text","text":"Cancel"}},{"type":"Button","child":{"type":"Text","text":"OK"}}]}]
}

A2UI 采用扁平的邻接表:

//A2UI 邻接表结构 - LLM 友好,支持增量生成
{
"surfaceUpdate":{
"components":[
{"id":"root","component":{"Column":{"children":{"explicitList":["greeting","buttons"]}}}},{"id":"greeting","component":{"Text":{"text":{"literalString":"Hello"}}}},{"id":"buttons","component":{"Row":{"children":{"explicitList":["cancel-btn","ok-btn"]}}}},{"id":"cancel-btn","component":{"Button":{"child":"cancel-text","action":{"name":"cancel"}}}},{"id":"cancel-text","component":{"Text":{"text":{"literalString":"Cancel"}}}},{"id":"ok-btn","component":{"Button":{"child":"ok-text","action":{"name":"ok"}}}},{"id":"ok-text","component":{"Text":{"text":{"literalString":"OK"}}}}]
}
}

邻接表的优势:

特性嵌套树邻接表
LLM 生成难度高(需一次性正确嵌套)低(逐个组件生成)
增量更新困难简单(按 ID 更新)
流式传输不支持原生支持
错误恢复整体失败单组件失败不影响其他

三、协议消息类型详解

A2UI 定义了 4 种服务端到客户端的消息类型:

3.1 surfaceUpdate - 定义 UI 结构
{
"surfaceUpdate":{
"surfaceId":"booking-form",
"components":[
{"id":"title","component":{"Text":{"text":{"literalString":"预订餐厅"},"usageHint":"h1"}}},{"id":"date-picker","component":{"DateTimeInput":{"value":{"path":"/reservation/date"},"enableDate":true,"enableTime":true}}}
]
}
}

关键点:

  • surfaceId:标识 UI 区域,支持多个独立 Surface
  • components:扁平组件列表,通过 ID 引用建立父子关系
  • 组件属性支持字面值或数据绑定
3.2 dataModelUpdate - 填充数据
{
"dataModelUpdate":{
"surfaceId":"booking-form",
"path":"/reservation",
"contents":[{"key":"date","valueString":"2025-12-20T19:00:00Z"},{"key":"guests","valueInt":2},{"key":"restaurant","valueMap":[{"key":"name","valueString":"川味轩"},{"key":"rating","valueNumber":4.8}]}]
}
}

设计亮点:

  • 数据与 UI 结构分离,修改数据无需重发组件定义
  • 支持嵌套数据结构(valueMap)
  • 类型安全(valueString/valueInt/valueBoolean/valueNumber)
3.3 beginRendering - 触发渲染
{
"beginRendering":{
"surfaceId":"booking-form",
"root":"title",
"catalogId":"https://github.com/google/A2UI/.../standard_catalog_definition.json"
}
}

为什么需要这个消息?

  • 防止"闪烁":客户端缓冲组件,等待明确信号再渲染
  • 指定根组件:从哪个组件开始构建树
  • 指定组件目录:告诉客户端使用哪套组件定义
3.4 deleteSurface - 清理 UI
{
"deleteSurface":{
"surfaceId":"booking-form"
}
}

四、完整数据流解析

下面是一个完整的餐厅预订场景数据流:

┌──────────────────────────────────────────────────────────────────┐
│ A2UI 数据流                                                       │
└──────────────────────────────────────────────────────────────────┘
用户:"帮我预订明晚7点的餐厅,2人"
▼
┌─────────────────┐
│ AI Agent        │ ← 接收用户请求,调用 LLM
│ (Python/Java)   │
└────────┬────────┘
│ 生成 A2UI JSON (JSONL 流)
▼
┌─────────────────────────────────────────────────────────────────┐
│ {"surfaceUpdate": {"surfaceId": "booking", "components": [...]}}│
│ {"dataModelUpdate": {"surfaceId": "booking", "contents": [...]}}│
│ {"beginRendering": {"surfaceId": "booking", "root": "form"}}    │
└─────────────────────────────────────────────────────────────────┘
│ 通过 SSE/WebSocket/A2A 传输
▼
┌─────────────────┐
│ Client App      │ ← 解析 JSONL,构建组件缓冲
│ (Angular/Lit)   │
└────────┬────────┘
│ 收到 beginRendering 后
▼
┌─────────────────┐
│ A2UI Renderer   │ ← 从 root 开始递归构建组件树
│                 │ ← 解析数据绑定,查询 WidgetRegistry
└────────┬────────┘
│
▼
┌─────────────────┐
│ Native UI       │ ← 渲染为原生组件(Material/Cupertino等)
│ (用户可见)      │
└────────┬────────┘
│ 用户点击"确认预订"按钮
▼
┌─────────────────────────────────────────────────────────────────┐
│ {"userAction": {
│  "name": "confirm_booking",
│  "surfaceId": "booking",
│  "context": {"date": "2025-12-20T19:00", "guests": 2}
│ }}
└─────────────────────────────────────────────────────────────────┘
│ 通过 A2A 消息发送回 Agent
▼
┌─────────────────┐
│ AI Agent        │ ← 处理用户操作,可能更新 UI 或完成任务
└─────────────────┘
4.1 用户点击"确认预订"后发生了什么?

这是一个关键问题:A2UI 只负责 UI 层,真正的业务逻辑由 Agent 决定。

当用户点击按钮后,Client 会将 userAction 发送回 Agent。Agent 收到后有多种处理方式:

┌─────────────────────────────────────────────────────────────────┐
│ 用户点击"确认预订"后的处理流程                                   │
└─────────────────────────────────────────────────────────────────┘
userAction 到达 Agent
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 方案 A      │ │ 方案 B      │ │ 方案 C      │
│ 模拟预订    │ │ 调用 API    │ │ 委托子Agent │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
直接返回确认UI 调用餐厅真实API 通过 A2A 委托
(Demo 场景) (MCP/HTTP) 专业预订 Agent
方案 A:模拟预订(Demo 场景)

当前示例代码采用的就是这种方式——Agent 直接生成确认 UI,不调用真实预订系统:

# Agent 收到 userAction 后,LLM 根据 Prompt 生成确认界面
# 这是 Demo 演示用,没有真实预订
# Prompt 中的指令:
# "For confirming a booking: use the CONFIRMATION_EXAMPLE template"

生成的确认 UI:

{
"surfaceUpdate":{
"components":[{"id":"confirm-title","component":{"Text":{"text":{"path":"title"}}}},{"id":"confirm-details","component":{"Text":{"text":{"path":"bookingDetails"}}}}]},
"dataModelUpdate":{
"surfaceId":"confirmation",
"contents":[{"key":"title","valueString":"预订成功!"},{"key":"bookingDetails","valueString":"川味轩 | 2人 | 明晚7点"}]}
}
方案 B:调用真实 API(生产场景)

在真实生产环境中,Agent 需要调用外部服务完成预订。这可以通过以下方式实现:

方式 1:Agent 内置 Tool(函数调用)

# 在 Agent 中定义预订工具
def book_restaurant( restaurant_id:str, date:str, time:str, guests:int, tool_context: ToolContext )->str:
    """调用餐厅预订 API"""
    response = requests.post("https://api.restaurant.com/bookings", json={"restaurant_id": restaurant_id,"datetime":f"{date}T{time}","party_size": guests }, headers={"Authorization":f"Bearer {API_KEY}"})
    return response.json()

# Agent 配置
agent = LlmAgent( tools=[get_restaurants, book_restaurant],
# 添加预订工具 instruction="当用户确认预订时,调用 book_restaurant 工具...")

方式 2:通过 MCP (Model Context Protocol) 调用

# Agent 通过 MCP 连接到餐厅预订服务
mcp_client = MCPClient("restaurant-booking-server")
# MCP 服务器暴露的工具
# - create_booking(restaurant_id, datetime, guests)
# - cancel_booking(booking_id)
# - get_availability(restaurant_id, date)
result = await mcp_client.call_tool("create_booking",{"restaurant_id":"chuanwei-001","datetime":"2025-12-20T19:00:00","guests":2})
方案 C:委托专业子 Agent(多 Agent 协作)

在复杂的多 Agent 系统中,主 Agent 可能将预订任务委托给专业的预订 Agent:

┌─────────────────────────────────────────────────────────────────┐
│ 多 Agent 协作预订流程                                             │
└─────────────────────────────────────────────────────────────────┘
┌──────────────┐ A2A 协议 ┌──────────────────┐
│ 主 Agent     │──────────>│ 预订专业 Agent   │
│ (对话协调)   │           │ (OpenTable集成)  │
└──────────────┘          └────────┬─────────┘
                                  │ │
                                  │ 调用真实 API
                                  ▼
                          ┌──────────────────┐
                          │ OpenTable API    │
                          │ 或其他预订平台   │
                          └──────────────────┘
# 主 Agent 通过 A2A 协议委托任务
async def delegate_booking(booking_details:dict):
    a2a_client = A2AClient("https://booking-agent.example.com")
    response = await a2a_client.send_message({"message":{"role":"user","parts":[{"kind":"data","data":{"task":"create_booking","details": booking_details }}]}})
    return response
4.2 A2UI 的职责边界

理解这一点很重要:

┌─────────────────────────────────────────────────────────────────┐
│ 职责分离                                                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ A2UI 协议负责:                                                  │
│ ├── UI 结构描述 (surfaceUpdate)                                 │
│ ├── 数据绑定 (dataModelUpdate)                                 │
│ ├── 用户交互事件传递 (userAction)                              │
│ └── 渲染控制 (beginRendering)                                  │
│                                                                 │
│ A2UI 协议不负责:                                                │
│ ├── 业务逻辑执行(预订、支付等)                               │
│ ├── 外部 API 调用                                                │
│ ├── 数据持久化                                                   │
│ └── 身份认证                                                     │
│                                                                 │
│ 业务逻辑由 Agent 通过以下方式实现:                             │
│ ├── 内置 Tools(函数调用)                                     │
│ ├── MCP 服务器                                                   │
│ ├── A2A 委托给专业子 Agent                                       │
│ └── 直接 HTTP/gRPC 调用                                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

简单来说:A2UI 是 UI 层协议,业务逻辑由 Agent 自行决定如何实现。

五、标准组件目录

A2UI v0.8 定义了以下标准组件:

类别组件说明
布局Row, Column, List排列子组件
展示Text, Image, Icon, Video, AudioPlayer, Divider展示内容
交互Button, TextField, CheckBox, DateTimeInput, Slider, MultipleChoice用户输入
容器Card, Tabs, Modal组织内容
组件示例:动态列表
// 使用 template 渲染动态列表
{
"surfaceUpdate":{
"components":[{"id":"restaurant-list","component":{"List":{"children":{"template":{"dataBinding":"/restaurants","componentId":"restaurant-card-template"}}}},{"id":"restaurant-card-template","component":{"Card":{"child":"card-content"}}}]}
}
}

六、组件目录协商机制

这是 A2UI 安全模型的核心:Agent 如何知道可以使用哪些组件?

6.1 协商流程
┌─────────────────────────────────────────────────────────────────┐
│ 组件目录协商流程                                                 │
└─────────────────────────────────────────────────────────────────┘
步骤 1: Agent 在 Agent Card 中声明支持的目录
↓
┌─────────────────────────────────────────────────────────────────┐
│ {
│  "name": "Restaurant Finder",
│  "capabilities": {
│    "extensions": [{
│      "uri": "https://a2ui.org/a2a-extension/a2ui/v0.8",
│      "params": {
│        "supportedCatalogIds": [
│          "https://github.com/google/A2UI/.../standard_catalog",
│          "https://my-company.com/custom_catalog"
│        ],
│        "acceptsInlineCatalogs": true
│      }
│    }]
│  }
│ }
└─────────────────────────────────────────────────────────────────┘
步骤 2: Client 在每条消息中声明自己支持的目录
↓
┌─────────────────────────────────────────────────────────────────┐
│ {
│  "metadata": {
│    "a2uiClientCapabilities": {
│      "supportedCatalogIds": [
│        "https://github.com/google/A2UI/.../standard_catalog"
│      ],
│      "inlineCatalogs": [
│        {
│          "catalogId": "my-app:custom-charts",
│          "components": {
│            "PieChart": { "type": "object", "properties": {...}}
│          }
│        }
│      ]
│    }
│  },
│  "message": { "prompt": { "text": "找餐厅" } }
│ }
└─────────────────────────────────────────────────────────────────┘
步骤 3: Agent 选择双方都支持的目录,在 beginRendering 中指定
↓
┌─────────────────────────────────────────────────────────────────┐
│ {
│  "beginRendering": {
│    "surfaceId": "main",
│    "catalogId": "https://github.com/google/A2UI/.../standard",
│    "root": "root-component"
│  }
│ }
└─────────────────────────────────────────────────────────────────┘
6.2 LLM 如何被约束只使用已知组件?

关键在于 Prompt Engineering + JSON Schema 约束:

# Agent 开发者在调用 LLM 时,将组件目录作为 Schema 约束传入
# 1. 加载客户端支持的组件目录
catalog = load_catalog("standard_catalog_definition.json")
# 2. 构建包含组件定义的 JSON Schema
resolved_schema = {
"properties":{
"surfaceUpdate":{
"properties":{
"components":{
"items":{
"properties":{
"component":{
# 这里只包含目录中定义的组件类型
"properties": catalog["components"]
}
}
}
}
}
}
}
}
# 3. 使用 Structured Output 模式调用 LLM
response = llm.generate(
 prompt="生成一个餐厅预订表单",
 response_schema=resolved_schema # LLM 只能输出符合 Schema 的 JSON
)

约束机制:

层级约束方式说明
LLM 层JSON Schema / Structured Output现代 LLM(GPT-4、Gemini)支持强制输出符合 Schema 的 JSON
Agent 层Prompt 中包含组件目录告诉 LLM 可用的组件类型和属性
协议层目录协商Client 声明支持的目录,Agent 只能选择其中之一
渲染层组件白名单Client 渲染器只渲染已注册的组件类型
6.3 如果 Agent 发送了未知组件会怎样?
// Agent 错误地发送了一个不存在的组件
{
"surfaceUpdate":{
"components":[{"id":"evil","component":{"ScriptExecutor":{//不在目录中
"code":"alert('hacked')"}}}
]
}
}

Client 的处理方式:

  1. 忽略未知组件:渲染器在 WidgetRegistry 中找不到 ScriptExecutor,跳过该组件
  2. 显示占位符:渲染一个错误提示组件
  3. 发送错误消息:通过 error 消息通知 Agent
// Client 返回错误
{
"error":{
"type":"unknown_component",
"componentId":"evil",
"componentType":"ScriptExecutor",
"message":"Component type 'ScriptExecutor' is not in the supported catalog"
}
}
6.4 自定义组件的安全扩展

如果业务需要自定义组件(如图表、地图),流程如下:

┌─────────────────────────────────────────────────────────────────┐
│ 自定义组件安全流程                                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ 1. Client 开发者实现自定义组件(本地代码,完全可控)             │
│ class PieChartComponent { render(data) { ... } }                │
│                                                                 │
│ 2. 在 WidgetRegistry 中注册                                      │
│ registry.register("PieChart", PieChartComponent)                │
│                                                                 │
│ 3. 定义组件 Schema,加入自定义目录                               │
│ { "PieChart": { "properties": { "data": {...} } } }             │
│                                                                 │
│ 4. 在 a2uiClientCapabilities 中声明支持该目录                    │
│                                                                 │
│ 5. Agent 现在可以安全地使用 PieChart 组件                        │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

安全保证:自定义组件的实现代码在 Client 侧,Agent 只能传递数据参数,无法注入逻辑。

七、安全模型总结

┌────────────────────────────────────────────────────────┐
│ A2UI 安全边界                                            │
├────────────────────────────────────────────────────────┤
│ Agent 侧(不可信)              │ Client 侧(可信)     │
│ ─────────────────               │ ─────────────────     │
│ • 生成 JSON 描述                  │ • 定义组件目录        │
│ • 只能引用已知组件类型          │ • 实现组件渲染逻辑    │
│ • 无法执行任意代码              │ • 控制样式和行为      │
│ • 受 JSON Schema 约束             │ • 验证数据绑定        │
└────────────────────────────────────────────────────────┘

关键安全特性:

  1. 声明式数据:Agent 发送的是数据,不是代码
  2. 组件白名单:只能使用客户端预定义的组件
  3. 目录协商:双向声明,取交集
  4. Schema 约束:LLM 输出受 JSON Schema 强制约束
  5. 无 eval/innerHTML:客户端渲染器不执行任意字符串
  6. 数据绑定验证:路径解析在客户端控制

八、总结

A2UI 通过精巧的协议设计,解决了 AI Agent 生成 UI 的核心挑战:

挑战A2UI 解决方案
安全性声明式 JSON + 组件白名单
LLM 生成难度邻接表模型 + 流式传输
跨平台抽象组件 + 客户端渲染
性能数据/结构分离 + 增量更新

如果你正在构建 AI Agent 应用,A2UI 值得深入研究。它代表了 Agent UI 领域的最佳实践。


参考资料:

  • A2UI GitHub 仓库
  • A2UI 官方文档
  • A2UI v0.8 协议规范

目录

  1. 一、A2UI 是什么?
  2. 二、核心设计理念
  3. 2.1 三层解耦架构
  4. 2.2 邻接表模型 vs 嵌套树
  5. 三、协议消息类型详解
  6. 3.1 surfaceUpdate - 定义 UI 结构
  7. 3.2 dataModelUpdate - 填充数据
  8. 3.3 beginRendering - 触发渲染
  9. 3.4 deleteSurface - 清理 UI
  10. 四、完整数据流解析
  11. 4.1 用户点击"确认预订"后发生了什么?
  12. 方案 A:模拟预订(Demo 场景)
  13. Agent 收到 userAction 后,LLM 根据 Prompt 生成确认界面
  14. 这是 Demo 演示用,没有真实预订
  15. Prompt 中的指令:
  16. "For confirming a booking: use the CONFIRMATION_EXAMPLE template"
  17. 方案 B:调用真实 API(生产场景)
  18. 在 Agent 中定义预订工具
  19. Agent 配置
  20. 添加预订工具 instruction="当用户确认预订时,调用 book_restaurant 工具...")
  21. Agent 通过 MCP 连接到餐厅预订服务
  22. MCP 服务器暴露的工具
  23. - createbooking(restaurantid, datetime, guests)
  24. - cancelbooking(bookingid)
  25. - getavailability(restaurantid, date)
  26. 方案 C:委托专业子 Agent(多 Agent 协作)
  27. 主 Agent 通过 A2A 协议委托任务
  28. 4.2 A2UI 的职责边界
  29. 五、标准组件目录
  30. 组件示例:动态列表
  31. 六、组件目录协商机制
  32. 6.1 协商流程
  33. 6.2 LLM 如何被约束只使用已知组件?
  34. Agent 开发者在调用 LLM 时,将组件目录作为 Schema 约束传入
  35. 1. 加载客户端支持的组件目录
  36. 2. 构建包含组件定义的 JSON Schema
  37. 这里只包含目录中定义的组件类型
  38. 3. 使用 Structured Output 模式调用 LLM
  39. 6.3 如果 Agent 发送了未知组件会怎样?
  40. 6.4 自定义组件的安全扩展
  41. 七、安全模型总结
  42. 八、总结

更多推荐文章

查看全部
  • Diffusion Transformer(DiT):将 U-Net 换成 ViT,应用于视频生成与机器人动作预测
  • 开源 Pixhawk 飞控无人机装调与测试实战指南
  • OFDM 完整通信链路项目 FPGA 开发:开发板硬件片内测试
  • 扣子(Coze)Skills 与 OpenClaw 智能体应用实战
  • DEIM 实时目标检测算法在 VisDrone2019 无人机数据集上的实战
  • FPGA 实现多路高精度 AD1246 高速数据采集与接收设计
  • 基于 Next.js 构建支持 TokenP 钱包登录的 DApp 前端
  • Seedance 2.0 实测:AI 视频从“能看”走向“能用”
  • C++内存模型演示:代码、原理与注意事项
  • 基于 Python 和 Uniapp 的高校科研经费管理系统设计与实现
  • 利用 MaaS 平台 API 构建本地智能 AI 助手
  • MCP 协议详解:与 Function Call 的区别及使用方式
  • Google AI Studio 使用指南:Gemini 3.0 Pro 参数配置与系统指令优化
  • AI Agent 记忆系统技术综述:架构、范式与评估
  • Prompt 工程实战:从基础结构到场景化应用
  • pip 实操笔记:安装、虚拟环境与常见报错
  • OpenClaw 搭建飞书 AI 办公机器人:接入 Ollama 与 Skills 自动化
  • 大模型微调的核心三要素:算法、数据与算力
  • 利用检索增强生成(RAG)降低大模型幻觉与虚假信息
  • Python 数据分析全流程指南:从基础到建模实战

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online