图标新增除上传文件外,前端可从第三方图标库直接选取(已是字符串)。 新增 POST /admin/icon/parse-svg-text 做入库前预校验(同 parse-svg 安全口径); 第三方库字符串也可直接走 POST /admin/icon/item 保存(保存接口本就同款校验)。 测试服实测通过(合法200/script拒210757/空白400/中文按字节计)。
7.9 KiB
【新增接口·管理后台】图标库 新增 parse-svg-text(支持第三方图标库直传 SVG 字符串校验)
PR: #3437 | 关联工单: #3434 服务: hl-user-service | 更新时间: 2026-06-04
存放目录:
changelogs-v2/2026-06/影响范围: 管理后台「图标库」图标新增/编辑页——新增图标的「来源」除「上传 SVG 文件」外,新增「从第三方图标库选取」路径
⚠️ 关键说明
-
新输入路径:前端反馈,除了上传
.svg文件,运营还可以从前端集成的第三方图标库(iconfont / 图标组件库等)直接选取图标,此时前端已经拿到 SVG 字符串,无需"上传文件 → 后端解析"这一步。 -
两条保存路径都支持,二选一:
路径 调用 适用 A. 直接保存 POST /admin/icon/item(svgContent直接传字符串)第三方库字符串本就能直接保存——保存接口的 svgContent一直是字符串字段,且后端保存时第一步即做同款安全校验B. 先预校验再保存(推荐) POST /admin/icon/parse-svg-text预校验 → 填表单 →POST /admin/icon/item保存与「上传文件」路径( parse-svg→ 保存)UX 对称,错误早暴露:含<script>/DOCTYPE 等浏览器能渲染、后端会拒的内容,选取后立即报错,不必等填完整张表单点保存才发现 -
安全口径完全一致:
parse-svg-text与文件路径parse-svg、以及保存接口共用同一套服务端校验(XXE-safe 解析 + 拒<script>/<foreignObject>/on*事件属性/javascript:外链 + ≤256KB)。parse-svg-text仅校验、不落库;落库仍走保存接口(保存时二次校验,纵深防御)。前端内联渲染 SVG 时仍建议先做一次 sanitize。 -
本次纯加性:不改动任何已有端点(
parse-svg/item/ 查询等契约全部不变)。
1. 接口背景
图标库新增图标原流程(上传文件):
上传 .svg 文件 → POST /admin/icon/parse-svg(解析+校验,返回字符串)→ 回填表单 → POST /admin/icon/item(保存)
新增「第三方库选取」路径,前端已持有字符串,对称流程:
第三方库选取(拿到 SVG 字符串)→ POST /admin/icon/parse-svg-text(校验,返回字符串)→ 回填表单 → POST /admin/icon/item(保存)
2. 变更清单
| # | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|
| 1 | POST | /admin/icon/parse-svg-text |
新增 | 校验前端直传的 SVG 字符串(来自第三方库),仅校验不落库 |
网关路由
/admin/icon/**已是通配,本端点自动覆盖,无需前端额外处理路由。
3. 接口详情
3.1 校验前端直传的 SVG 字符串
POST /admin/icon/parse-svg-text
- 使用场景:从第三方图标库选取图标(已是字符串)后,保存前做合法性 + 安全校验
- 认证:管理后台 JWT
- 幂等:是(仅校验,不落库)
Body 入参(IconSvgParseTextReqVO):
| 字段 | 类型 | 必填 | 校验 | 说明 |
|---|---|---|---|---|
svgContent |
string | ✅ | @NotBlank + @Size(max=262144) |
第三方库选取的原始 SVG 字符串(UTF-8 文本) |
出参:Result<IconSvgParseRespVO>(与 parse-svg 复用同一响应 VO)
| 字段 | 类型 | 说明 |
|---|---|---|
svgContent |
string | 校验通过的 SVG 字符串(原样回填保存表单) |
fileName |
string | 恒为 null(非文件来源,仅文件上传路径才有值) |
size |
long | 内容字节数(UTF-8 编码),非字符数 |
典型示例 请求:
curl -X POST "https://api.test.1814.love:9443/admin/icon/parse-svg-text" \
-H "Authorization: Bearer <adminToken>" \
-H "Content-Type: application/json" \
-d '{"svgContent":"<svg viewBox=\"0 0 24 24\"><path d=\"M0 0h24v24H0z\"/></svg>"}'
典型示例 响应(测试服实测):
{
"code": 200,
"data": {
"svgContent": "<svg viewBox=\"0 0 24 24\"><path d=\"M0 0h24v24H0z\"/></svg>",
"fileName": null,
"size": 56
},
"message": "成功"
}
异常 响应(SVG 含脚本/事件/外链,测试服实测):
{ "code": 210757, "message": "SVG 含不安全内容(脚本/事件/外链),请清理后重试", "data": null }
异常 响应(svgContent 为空/纯空白,@NotBlank 拦截):
{ "code": 400, "message": "SVG 内容不能为空", "data": null }
3.2 保存图标(已有接口,未变,此处仅提示第三方库路径如何用)
POST /admin/icon/item
第三方库选取的字符串可直接作为 svgContent 传入保存,无需先上传成文件。保存接口本就对 svgContent 做同款安全校验(见 §6 错误码)。完整字段契约见图标库模块首推 changelog 03_3390_图标库模块... §3.6,本次未改动。
4. 前端动作(mmg)
- 图标新增/编辑页加"来源"选择:现有「上传 SVG 文件」之外,加「从第三方图标库选取」。
- 第三方库选取后(推荐路径 B):拿到 SVG 字符串 → 调
POST /admin/icon/parse-svg-text预校验 → 成功则用返回的svgContent回填表单(同上传文件路径的回填逻辑)→ 失败则按 §6 错误码提示用户更换图标。 - 或直接保存(路径 A):若不想加预校验步骤,可把第三方库字符串直接放进
POST /admin/icon/item的svgContent,保存接口会做同款校验并返回对应错误码。 - 渲染仍建议 sanitize:后端已拒明显恶意内容,前端内联渲染(
v-html/innerHTML)时再做一次 sanitize 作纵深防御。
5. 枚举 / 数据字典
无新增枚举。本端点不涉及状态/类型字段。
6. 错误码
| code | 含义 | 触发条件 | 涉及接口 |
|---|---|---|---|
| 400 | 参数校验失败 | svgContent 为空/纯空白(@NotBlank)或超 @Size(262144) |
§3.1 |
| 401 | 未登录 | admin JWT 无效或缺失 | §3.1 |
| 210754 | SVG 内容不合法 | 非合法 XML 或根元素不是 <svg> |
§3.1 §3.2 |
| 210755 | SVG 内容过大 | 超过 256KB(按 UTF-8 字节) | §3.1 §3.2 |
| 210757 | SVG 含不安全内容 | 含 <script> / <foreignObject> / on* 事件 / javascript: 外链 |
§3.1 §3.2 |
parse-svg-text的错误码是文件路径parse-svg的子集(无210753「文件为空」/210756「文件读取失败」——这两个仅文件上传场景有;字符串为空由@NotBlank在网关层返 400)。错误码段位 210700-210799 归属图标库模块。
7. 验证(测试服实测,已通过)
| 用例 | 输入 | 结果 |
|---|---|---|
| 合法字符串 | 标准 SVG | http200 / code200,svgContent 回显、fileName=null、size=56 |
含 <script> |
带脚本的 SVG | http200 / code210757 拒 |
| 空白串 | " " |
http200 / code400 SVG内容不能为空 |
| 中文 SVG | 含 <title>晴天</title> |
http200 / code200,size=83 > 字符数 79(证明按 UTF-8 字节计) |
- 单测
IconItemServiceTest36 全绿(含 script/事件/外链/foreignObject/超限/UTF-8 字节数等正反路径) - hl-user-service 双实例(8081 + 8181)均已部署新代码、health UP
8. 影响评估
- 是否破坏向后兼容:否(纯新增端点,无任何已有接口改动)
- 前端是否必须同步上线:是(新输入路径,前端按 §4 接入「第三方库选取」)
- 影响已有数据:无
9. 关联 / 联系人
- 本次 PR:#3437(Closes #3434)
- 图标库模块首推 changelog:
03_3390_图标库模块-新增接口-管理后台+小程序.md(含分类/图标/上传解析全量契约) - 后端负责人:@wx
- 前端对接(管理后台):mmg