Skip to content

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(修正为网关对外的域名)。

参数说明

  1. Mode (模式):决定如何处理版本号前缀。

    • NEVER_STRIP:即使原始请求路径不包含版本号,也不会剥离版本号。
    • AS_IN_REQUEST(默认值):仅当原始请求路径包含版本号时,才剥离版本号。
    • ALWAYS_STRIP:即使原始请求路径包含版本号,也始终剥离版本号。
  2. hostValue (主机值)

    • 如果提供了此参数,它将用于替换响应 Location 头中的 host:port 部分。
    • 如果未提供,则使用请求头中的 Host 值。
  3. protocols (协议)

    • 必须是一个有效的正则表达式 String,用于匹配协议名称。
    • 如果不匹配,过滤器将不做任何操作。
    • 默认值为 https?|ftps?(匹配 http, https, ftp, ftps)。

补充教学 —— 为什么要重写 Location 头?

场景:隐藏后端真实地址

  • 架构
    • 网关对外域名:api.mall.com
    • 后端订单服务(内网):order-service:8080
  • 流程
    1. 用户创建订单:POST https://api.mall.com/orders
    2. 网关转发给后端:POST http://order-service:8080/orders
    3. 后端处理成功,返回 201 Created,并带上 Location 头告诉客户端新资源的地址。
    4. 问题:后端不知道外网域名,它生成的 Location 是 http://order-service:8080/orders/1001
    5. 后果:如果不处理,客户端收到的重定向地址是内网地址,直接访问会报错(无法连接)。
  • 解决:使用 RewriteLocationResponseHeader
    • 网关拦截响应,看到 Location 头里的 order-service:8080
    • 网关把它替换成请求里的 Host api.mall.com
    • 最终客户端收到:https://api.mall.com/orders/1001,访问正常。

Based on Spring Framework.