美文网首页
spring cloud gateway跨域冲突功能的开发

spring cloud gateway跨域冲突功能的开发

作者: 爱余星痕 | 来源:发表于2020-08-12 15:13 被阅读0次

    gateway可以实现支持跨域功能,但如果下游也支持跨域,会出现跨域冲突。
    如何解决该问题,gateway对外输出相关跨域的httpheader,只要对重复的header去掉即可。

    
    /**
     * @author starmark
     * @date 2020/5/11  下午9:29
     */
    @Slf4j
    public class GatewayCorsWebFilter implements WebFilter {
        @Autowired
        private IRouteService routeService;
        private final CorsProcessor processor;
    
        private static List<String> configHeaderNames = new ArrayList<>();
        static{
            configHeaderNames.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS);
            configHeaderNames.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS);
            configHeaderNames.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS);
            configHeaderNames.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN);
            configHeaderNames.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS);
    
        }
    
        public GatewayCorsWebFilter() {
            this.processor = new DefaultCorsProcessor();
        }
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
            ServerHttpRequest request = exchange.getRequest();
            String url = request.getPath().value();
            if (url.contains("webjars") || url.contains("swagger-resources") || url.contains("/v2/api-docs") || url.contains("doc.html") || url.contains("swagger-ui.html") ||
                    url.contains(".css") || url.contains(".ico") || url.contains(".js") || url.contains(".png") || url.contains(".jpg")) {
                //如果发现是css或者js文件,直接放行
                return chain.filter(exchange);
            }
            String projectCode = RequestHelper.getRequestProjectCode(request);
            Assert.hasText(projectCode, "工程编码不存在");
            CorsConfiguration corsConfiguration = routeService.getGatewayProjectCorsConfiguration(projectCode);
            boolean isValid = this.processor.process(corsConfiguration, exchange);
    
            if (!isValid || CorsUtils.isPreFlightRequest(request)) {
                return Mono.empty();
            }
            //解决跨域冲突的问题
            ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(exchange.getResponse()) {
    
                @Override
                public HttpHeaders getHeaders() {
                    HttpHeaders httpHeaders=    HttpHeaders.writableHttpHeaders(getDelegate().getHeaders());
                    dedupe(httpHeaders);
                    return httpHeaders;
                }
                void dedupe(HttpHeaders headers) {
                    if (headers == null) {
                        return;
                    }
                    for (String name : configHeaderNames) {
                        dedupe(headers, name.trim());
                    }
                }
    
                private void dedupe(HttpHeaders headers, String name) {
                    List<String> values = headers.get(name);
                    if (values == null || values.size() <= 1) {
                        return;
                    }
    
                    headers.set(name, values.get(values.size() - 1));
    
                }
            };
            return chain.filter(exchange.mutate().response(decoratedResponse).build());
        }
    
    
    
    }
    
    

    上述是我跨域功能的代码,支持跨域功能及解决跨域冲突功能的问题。
    上面有一个梗, exchange.getResponse().getHeaders()的header为只读,需要通过构造响应ServerHttpResponseDecorator 来解决只读的问题。

    相关文章

      网友评论

          本文标题:spring cloud gateway跨域冲突功能的开发

          本文链接:https://www.haomeiwen.com/subject/gstmdktx.html