Agent输出Markdown/HTML格式化统一处理
开发中,Agent返回的内容经常同时混有Markdown和HTML片段,直接渲染不是样式错乱就是存在XSS风险。本文围绕Agent输出Markdown/HTML格式化统一处理与前端渲染适配,给出一个能直接落地的中转方案:先用Node.js统一转换和清洗,再让前端以安全HTML方式渲染。零基础用户按步骤操作即可完成。
## 为什么需要统一处理
Agent 生成的文本可能包含 `# 标题`、`**加粗**` 这类 Markdown 语法,也可能直接返回 `加粗`、`链接` 这样的 HTML 片段。如果前端不做任何处理直接展示,会出现两种问题:一是 Markdown 变成纯文本,排版丢失;二是未经过滤的 HTML 可能携带脚本,带来安全风险。
统一处理的目标很简单:把所有内容先转成 HTML,再做安全过滤,最后给前端一份干净的 HTML。这样无论 Agent 输出哪种格式,最终渲染效果一致。
## 准备环境
本文使用 Node.js + Express 搭建一个中间层服务。需要准备:
- Node.js 16 或更高版本
- npm(安装 Node.js 时会自动安装)
- 一个可用的 Agent 接口,能返回混合格式文本
先在空目录里初始化项目:
```bash
npm init -y
npm install express marked dompurify jsdom
```
`marked` 负责把 Markdown 转为 HTML,`dompurify` 配合 `jsdom` 负责清洗 HTML,去除脚本和危险属性。
## 实现统一格式化中间层
新建 `server.js`,写入以下代码:
```js
const express = require('express');
const { JSDOM } = require('jsdom');
const createDOMPurify = require('dompurify');
const { marked } = require('marked');
const app = express();
app.use(express.json());
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
// 统一转换函数:Markdown 和 HTML 都变为安全 HTML
function formatAgentContent(input) {
// 先转 Markdown,如果已经是 HTML,marked 也会保留原样
const rawHtml = marked.parse(input || '');
// 再清洗,去掉脚本、事件属性等危险内容
const cleanHtml = DOMPurify.sanitize(rawHtml);
return cleanHtml;
}
app.post('/api/format', (req, res) => {
const { content } = req.body;
res.json({ html: formatAgentContent(content) });
});
app.listen(3000, () => console.log('格式化服务运行在 3000 端口'));
```
启动服务:
```bash
node server.js
```
测试时发送请求:
```bash
curl -X POST http://localhost:3000/api/format \
-H "Content-Type: application/json" \
-d '{"content":"# 标题\n\n\n\n**加粗**"}'
```
返回的 HTML 中,`
```
如果担心页面样式冲突,可以把容器内的样式写成独立作用域,例如给所有子元素设置默认字体和间距。
## 避坑清单与验证结果
**常见坑**
- 不要省略 DOMPurify 清洗步骤,否则 `
`、`javascript:` 链接等危险内容可能被浏览器执行。
- `marked` 默认不会执行 HTML 里的脚本,但会保留标签,所以必须先清洗再返回。
- 如果 Agent 输出的内容里包含代码块,`marked` 会保留语法高亮用的 class,前端需要引入对应的代码高亮样式。
**验证方法**
1. 构造包含 `` 的 Markdown 文本,请求接口后确认 `alert` 不会弹出。
2. 输入 `# 标题`,确认返回的是 `
` 标签。 3. 输入 `
段落
`,确认返回的 HTML 中标签被保留且没有额外转换。 完成以上验证,说明你的 Agent 输出格式化与前端渲染链路已经可用。后续如果遇到新格式,只需要在中间层增加规则,前端代码基本不用改。建议先按本文步骤完整执行,再根据自己的环境微调;遇到异常时优先回看避坑和高频问题部分。