xml上传接口需显式配置网关解析:kong须启用body-parser插件并添加application/xml到allowed_content_types,Tyk需在proxy中设enable_xml:true;二者均需先解析body再提取字段供校验、限流或JWT策略使用。

XML上传接口不能直接套用常规 REST 策略,核心问题在于:网关默认按 Content-Type: application/json 解析请求体,而 XML 请求的 Content-Type 通常是 application/xml 或 text/xml,Kong/Tyk 若未显式配置,会跳过 body 解析、无法做 schema 校验、限流或 JWT 提取字段等操作。
为什么 Kong 默认不处理 XML body
Kong 的 request-transformer 和 body-parser 插件默认只解析 application/json 和 application/x-www-form-urlencoded。遇到 application/xml 时,ngx.var.request_body 可能为空或未触发解析流程,导致后续插件(如 rate-limiting 基于 header/body 的策略、jwt-keycloak 提取 XML 中的 Token 字段)全部失效。
- 现象:
curl -H "Content-Type: application/xml" -d '发送后,Kong 日志中 ' https://api.example.com/upload123 request_body为 nil - 根本原因:openresty 的
ngx.req.read_body()需手动触发,且 Kong 插件链默认不为 XML 注册解析器 - 解决路径:必须启用并配置
body-parser插件,显式声明支持的 MIME 类型
Kong 中启用 XML body 解析与校验
在服务或路由级别启用 body-parser 插件,并补充 XML 支持;再配合 request-validator(需安装插件)做 XSD 校验:
- 启用插件:
{"name": "body-parser", "config": {"allowed_content_types": ["application/json", "application/xml", "text/xml"], "parse_error_as_json": true}} - 注意:
allowed_content_types必须包含application/xml,否则 Kong 仍跳过解析 - 若需校验 XML 结构,安装社区版
request-validator插件后,配置xsd_schema字段指向已上传的 XSD 文件(路径需在 Kong 数据库或挂载卷中可访问) - 限流策略若依赖 XML 内容(如按
分组),需搭配request-transformer提取字段并写入 header:{"name": "request-transformer", "config": {"add": {"headers": ["X-Tenant-ID: ${{ xml['tenant_id'] }}"]}, "replace": {}}}
Tyk 中配置 XML 上传策略的关键差异
Tyk 对 XML 支持更原生,但配置位置和行为逻辑不同:body 解析由网关层自动完成(只要 Content-Type 匹配),但策略生效依赖 enable_xml 开关和正确的中间件顺序:
- 在 API 定义的
proxy配置中,必须设"enable_xml": true,否则 Tyk 不加载 XML 解析器 - JWT 或 OAuth2 策略若需从 XML body 提取 token(如
),需在abc middleware.driver中指定xml模式,并在auth_token_path使用 XPath 表达式:/auth/token/text() - 速率限制若基于 XML 字段,需在
advanced_rate_limit中使用per_ip+per_path组合,并通过header_map将提取的字段映射到限流 key —— 直接读 XML body 不被支持,必须先转成 header - 注意:Tyk 的
XML to JSON转换默认开启,但会扁平化嵌套结构(c→{"a.b": "c"}),XSD 校验需额外集成外部服务(如用自定义 JS 中间件调用libxmljs)
真正卡住人的不是“能不能配”,而是 XML body 在网关生命周期中的解析时机 —— Kong 要手动开解析、Tyk 要手动开开关,且两者都要求字段提取必须发生在 body 解析之后、策略执行之前。漏掉任一环,400 Bad Request 或静默失败就来了。