跳到主要内容
版本:3.10.x

API7 网关 AI Agent Skill:response-rewrite 插件

概览

response-rewrite 插件会在 API7 企业版向客户端返回响应前重写响应属性。 该插件会将响应返回给客户端。你可以无条件或根据匹配条件修改 HTTP 状态码、响应头和响应体。它在 header_filterbody_filter 阶段运行,因此即使前置插件(例如认证插件)调用 ngx.exit,它也会执行。

适用场景

  • 覆盖返回给客户端的 HTTP 状态码。
  • 添加、设置或移除响应头(例如安全请求头、CORS)。
  • 替换整个响应体(静态内容、错误消息)。
  • 使用正则表达式过滤器修改响应体的部分内容。
  • 有条件地应用响应修改(例如仅针对特定状态码)。
  • 提供经过 Base64 解码的二进制内容(图像、protobuf)。

插件配置参考(路由/服务)

字段类型是否必填默认值说明
status_codeinteger新的 HTTP 状态码(200–598)。如果未设置,则使用原始状态码。
bodystring新的响应体。Content-Length 会自动重置。不能与 filters 同时使用
body_base64booleanfalse在发送前将 body 从 Base64 解码。仅解码插件配置的响应体,不解码上游响应。
headersobject使用 setaddremove 字段操作请求头。
headers.setobject设置(覆盖)响应头。值为键值对,支持 NGINX 变量。
headers.addarray[string]追加响应头。例如:["Name: value", ...]。即使请求头已存在也会添加。
headers.removearray[string]移除响应头。要移除的请求头名称列表。
varsarray[array]使用 lua-resty-expr 语法进行条件匹配。仅当条件匹配时插件才会执行。
filtersarray[object]用于修改响应体的正则过滤器。不能与 body 同时使用
filters[].regexstring要在响应体中匹配的正则表达式。
filters[].replacestring替换内容。
filters[].scopestring"once""once" 表示仅替换首次匹配,"global" 表示替换所有匹配。
filters[].optionsstring"jo"正则表达式选项。参见 ngx.re.match

互斥关系bodyfilters 不能同时使用。

分步指南:在路由上启用 response-rewrite

1. 添加安全响应头

default 网关组添加安全请求头:

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "security-headers",
"uri": "/api/*",
"plugins": {
"response-rewrite": {
"headers": {
"set": {
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains"
},
"remove": ["Server", "X-Powered-By"]
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "backend", "port": 8080, "weight": 1}]
}
}
EOF

2. 自定义错误响应体

a7 route create --gateway-group prod -f - <<'EOF'
{
"id": "custom-error",
"uri": "/maintenance/*",
"plugins": {
"response-rewrite": {
"status_code": 503,
"body": "{\"error\": \"Service under maintenance\", \"retry_after\": 300}",
"headers": {
"set": {
"Content-Type": "application/json",
"Retry-After": "300"
}
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "backend", "port": 8080, "weight": 1}]
}
}
EOF

3. 条件重写(仅针对 200 响应)

a7 route create --gateway-group stage -f - <<'EOF'
{
"id": "conditional-rewrite",
"uri": "/api/*",
"plugins": {
"response-rewrite": {
"headers": {
"set": {
"Cache-Control": "public, max-age=3600"
}
},
"vars": [["status", "==", 200]]
}
},
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "backend", "port": 8080, "weight": 1}]
}
}
EOF

常见模式

正则响应体过滤器(全局替换文本)

使用公开 URL 替换响应体中的内部主机名:

{
"plugins": {
"response-rewrite": {
"filters": [
{
"regex": "http://internal\\.service\\.local",
"scope": "global",
"replace": "https://api.example.com"
}
]
}
}
}

多个正则过滤器

{
"plugins": {
"response-rewrite": {
"filters": [
{
"regex": "X-Amzn-Trace-Id",
"scope": "global",
"replace": "X-Trace-Id"
},
{
"regex": "\"debug\":\\s*true",
"scope": "global",
"replace": "\"debug\": false"
}
]
}
}
}

Base64 响应体(提供二进制内容)

{
"plugins": {
"response-rewrite": {
"status_code": 200,
"body": "SGVsbG8gV29ybGQ=",
"body_base64": true,
"headers": {
"set": {
"Content-Type": "text/plain"
}
}
}
}
}

返回解码后的响应体:Hello World

添加动态服务器信息请求头

{
"plugins": {
"response-rewrite": {
"headers": {
"set": {
"X-Served-By": "$balancer_ip:$balancer_port",
"X-Request-Id": "$request_id"
}
}
}
}
}

条件重写:仅重写 5xx 错误

{
"plugins": {
"response-rewrite": {
"body": "{\"error\": \"internal server error\", \"code\": 500}",
"headers": {
"set": {
"Content-Type": "application/json"
}
},
"vars": [["status", ">=", 500]]
}
}
}

重要注意事项

  • 执行阶段:在 header_filterbody_filter 阶段运行,因此即使前置插件(认证、限流)通过 ngx.exit 拒绝请求,也会执行。
  • 请求头操作顺序addremoveset
  • 响应体和 filters 互斥:不能同时设置 bodyfilters
  • Base64 解码:仅作用于插件配置的 body 字段,不作用于上游响应体。

故障排查

现象原因解决方法
响应体未改变同时设置了 bodyfilters只能选择一项:body 用于完整替换,filters 用于局部替换
状态码未改变status_code 不在有效范围内必须为 200–598
正则过滤器未匹配模式语法或转义有误测试正则表达式;使用 "jo" 选项支持 UTF-8
移除后请求头仍存在请求头名称大小写不匹配请求头名称不区分大小写;检查拼写是否准确
Vars 条件未生效运算符或类型错误使用 lua-resty-expr 语法:["status", "==", 200](整数而非字符串)
认证失败时仍执行重写这是预期行为无论前置 ngx.exit 调用如何,插件都会在过滤阶段运行
Content-Length 不匹配手动设置了 Content-Length 请求头不要手动设置 Content-Length,插件会自动重置该字段
配置未生效指定了错误的网关组确保 --gateway-group 与目标集群一致

配置同步示例

version: "1"
gateway_group: default
routes:
- id: response-transform
uri: /api/*
plugins:
response-rewrite:
headers:
set:
X-Content-Type-Options: "nosniff"
X-Frame-Options: "DENY"
remove:
- Server
- X-Powered-By
vars:
- ["status", "==", 200]
upstream:
type: roundrobin
nodes:
- host: backend
port: 8080
weight: 1

本页面由 api7/a7 仓库中的 a7-plugin-response-rewrite/SKILL.md 生成。你可以在 AI Agent Skills 页面查看所有技能。