You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Gateway自定义路由过滤器禁用重定向问题求助

Fixing Unexpected Redirects When Modifying Gateway Route URL in Spring Cloud Greenwich.SR1

Let's start by unpacking why you're seeing that redirect behavior: when you set GATEWAY_REQUEST_URL_ATTR to point to http://example.com, the Gateway's NettyRoutingFilter forwards the request as expected. But if the target server returns a 3xx redirect response, Gateway's default logic kicks in—it rewrites the Location header in the response to match your original gateway URL. That's why your browser gets a redirect instruction, and trying to reset the Location header back to the original URL just creates a recursive loop (browser hits original URL, Gateway routes to example.com, repeats).

Here are actionable solutions tailored to your Greenwich.SR1 version:

Solution 1: Internal Redirect Following (Prevent Browser Redirects)

The cleanest fix is to make Gateway handle the redirect internally instead of sending it to the browser. This way, the user's address bar stays on the original URL, and Gateway silently forwards the request to the redirected target.

Create a custom filter to follow redirects at the gateway level:

@Component
public class InternalRedirectFollowFilter extends AbstractGatewayFilterFactory<InternalRedirectFollowFilter.Config> {

    private final HttpClient httpClient;

    public InternalRedirectFollowFilter(HttpClient httpClient) {
        super(Config.class);
        this.httpClient = httpClient;
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.defer(() -> {
                ServerHttpResponse response = exchange.getResponse();
                // Check if the response is a 3xx redirect
                if (response.getStatusCode() != null && response.getStatusCode().is3xxRedirection()) {
                    String redirectLocation = response.getHeaders().getFirst(HttpHeaders.LOCATION);
                    if (redirectLocation != null) {
                        try {
                            URI redirectUri = new URI(redirectLocation);
                            // Build a new request to the redirected location
                            ServerHttpRequest redirectedRequest = exchange.getRequest().mutate()
                                    .uri(redirectUri)
                                    .build();
                            // Send the internal request and copy the response back to the browser
                            return httpClient.sendRequest(redirectedRequest)
                                    .flatMap(clientResponse -> {
                                        response.setStatusCode(clientResponse.statusCode());
                                        response.getHeaders().addAll(clientResponse.headers().asHttpHeaders());
                                        return response.writeWith(clientResponse.bodyToFlux(DataBuffer.class));
                                    });
                        } catch (URISyntaxException e) {
                            return Mono.error(new IllegalArgumentException("Invalid redirect location: " + redirectLocation, e));
                        }
                    }
                }
                return Mono.empty();
            }));
        };
    }

    public static class Config {
        // Add configurable properties here if needed
    }
}

Then add this filter to your route configuration, making sure it runs after the NettyRoutingFilter (Gateway executes filters in the order they're defined, so place it after routing filters).

Solution 2: Disable Default Location Rewriting (For Non-Redirect Targets)

If your target server doesn't return redirects and you're still seeing unexpected redirects, check if Gateway's default location rewriting is interfering. You can disable this behavior by customizing the response filter:

Create a filter that removes or overrides the Location header before it's sent to the browser:

@Component
public class DisableLocationRewriteFilter extends AbstractGatewayFilterFactory<DisableLocationRewriteFilter.Config> {

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                ServerHttpResponse response = exchange.getResponse();
                // Remove the Location header entirely if you don't want any redirect
                response.getHeaders().remove(HttpHeaders.LOCATION);
                // Alternatively, set it to a value that doesn't trigger a browser redirect
                // response.getHeaders().set(HttpHeaders.LOCATION, exchange.getRequest().getPath().value());
            }));
        };
    }

    public static class Config {}
}

Important Note: Don't set the Location header back to your original gateway URL—this is what caused the recursive loop. Either remove it or set it to a value that doesn't trigger a browser navigation.

Bonus: Check for Other Filter Conflicts

Double-check your filter chain for any other filters (like RedirectToGatewayFilterFactory) that might be triggering redirects. Also, if you can, consider upgrading to the latest patch version of Greenwich (e.g., Greenwich.SR6) as it fixes several routing and redirect-related bugs, though I know upgrading isn't always an option.

内容的提问来源于stack exchange,提问作者kassie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:36:47