RewriteLocationResponseHeader GatewayFilter 工厂
RewriteLocationResponseHeader GatewayFilter 工厂用于修改响应头中 Location 的值,通常是为了去除后端特定的细节(如内部域名或端口)。
该过滤器接受 Mode(模式)、locationHeaderName(位置头名称)、hostValue(主机值)和 protocols(协议)四个参数。
以下示例配置了一个 RewriteLocationResponseHeader GatewayFilter:
application.yml
yaml
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,示例效果: 假设请求是 POST https://api.example.com/some/object/name。 后端返回的 Location 响应头值是 https://object-service.prod.example.net/v2/some/object/id(暴露了内部服务域名)。 经过该过滤器处理后,Location 头会被重写为 https://api.example.com/some/object/id(修正为网关对外的域名)。
参数说明
Mode (模式):决定如何处理版本号前缀。
NEVER_STRIP:即使原始请求路径不包含版本号,也不会剥离版本号。AS_IN_REQUEST(默认值):仅当原始请求路径不包含版本号时,才剥离版本号。ALWAYS_STRIP:即使原始请求路径包含版本号,也始终剥离版本号。
hostValue (主机值):
- 如果提供了此参数,它将用于替换响应
Location头中的host:port部分。 - 如果未提供,则使用请求头中的
Host值。
- 如果提供了此参数,它将用于替换响应
protocols (协议):
- 必须是一个有效的正则表达式
String,用于匹配协议名称。 - 如果不匹配,过滤器将不做任何操作。
- 默认值为
https?|ftps?(匹配 http, https, ftp, ftps)。
- 必须是一个有效的正则表达式
补充教学 —— 为什么要重写 Location 头?
场景:隐藏后端真实地址
- 架构:
- 网关对外域名:
api.mall.com - 后端订单服务(内网):
order-service:8080
- 网关对外域名:
- 流程:
- 用户创建订单:
POST https://api.mall.com/orders - 网关转发给后端:
POST http://order-service:8080/orders - 后端处理成功,返回 201 Created,并带上
Location头告诉客户端新资源的地址。 - 问题:后端不知道外网域名,它生成的 Location 是
http://order-service:8080/orders/1001。 - 后果:如果不处理,客户端收到的重定向地址是内网地址,直接访问会报错(无法连接)。
- 用户创建订单:
- 解决:使用
RewriteLocationResponseHeader。- 网关拦截响应,看到
Location头里的order-service:8080。 - 网关把它替换成请求里的 Host
api.mall.com。 - 最终客户端收到:
https://api.mall.com/orders/1001,访问正常。
- 网关拦截响应,看到