springcloud gateway 跨域解决方案

springcloud gateway 跨域解决方案

问题

springcloud gateway提供的自带的跨域过滤器有问题,前端还是会报跨域。zuul不会有这个问题。调试发现主要是游览器发送嗅探请求(OPTIONS)时,没有返回跨域的响应头,从而游览器报跨域问题。

验证

由于springcloud gateway为webflux与zuul不一样,同一个服务,采用spring内置的跨域过滤器,zuul可以通过而gateway报错。具体配置如下:

  1. gateway跨域配置
spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            # 允许携带认证信息
            # 允许跨域的源(网站域名/ip),设置*为全部
            # 允许跨域请求里的head字段,设置*为全部
            # 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
            # 跨域允许的有效期
            allow-credentials: true
            allowed-origins: '*'
            allowed-headers: Content-Type,Content-Length, Authorization, Accept,X-Requested-With
            allowed-methods: '*'
            exposed-headers: Content-Type,Content-Length, Authorization, Accept,X-Requested-With
            max-age: 3600

此配置无效,前端还是会报跨域问题,主要是前端发送OPTIONS请求时没有返回跨域信息

  1. zuul网关或者其它微服务servlet ,向容器中注入跨域过滤器

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * @author ZhouChuGang
 * @version 1.0
 * @project langangkj-commonm
 * @date 2020/5/4 12:24
 * @Description 跨域过滤器配置
 */
@Slf4j
@configuration
@ConditionalOnMissingBean(CorsFilter.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class CorsFilterConfiguration {

    public CorsFilterConfiguration() {
        log.info("==========注入跨域过滤器=============");
    }

    @Bean("corsFilter")
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        // #允许向该服务器提交请求的URI,*表示全部允许
        config.addAllowedOrigin(CorsConfiguration.ALL);
        // 允许cookies跨域
        config.setAllowCredentials(true);
        // #允许访问的头信息,*表示全部
        config.addAllowedHeader(CorsConfiguration.ALL);
        // 允许提交请求的方法,*表示全部允许
        config.addAllowedMethod(CorsConfiguration.ALL);
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

    @Autowired
    @Qualifier("corsFilter")
    private CorsFilter corsFilter;

    /**
     * 配置跨域过滤器
     */
    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilterRegistration() {
        FilterRegistrationBean<CorsFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(corsFilter);
        registration.addUrlPatterns("/*");
        registration.setName("corsFilter");
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registration;
    }
}

此方案可以完美解决跨域问题。但是springcloud gateway 不是servlet 规范。

解决方案

  1. gateway后面的微服务实现跨域。跨域由网关后面的服务实现。

  2. 实现一个过滤器,来做跨域允许。需要在响应头中加入以下信息

# 这个为请求头中的 origin
add_header 'Access-Control-Allow-Origin' '$http_origin' ;
add_header 'Access-Control-Allow-Credentials' 'true' ;
add_header 'Access-Control-Allow-Methods' 'PUT,POST,GET,DELETE,OPTIONS' ;
add_header 'Access-Control-Allow-Headers' 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With' ;

  1. 采用nginx做代理,配置跨域响应头。(强烈推荐
    请求先到nginx,nginx再去请求gateway, 由nginx添加跨域响应头
add_header 'Access-Control-Allow-Origin' '$http_origin' ;
add_header 'Access-Control-Allow-Credentials' 'true' ;
add_header 'Access-Control-Allow-Methods' 'PUT,POST,GET,DELETE,OPTIONS' ;
add_header 'Access-Control-Allow-Headers' 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With' ;

这里本人为了方便,采用第3中方案,测试完美解决

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud GatewaySpring Cloud生态圈中的一个API网关,它提供了一种构建微服务架构的解决方案。跨域是Web开发中常见的问题,特别是在微服务架构中,不同服务之间需要进行跨域访问。本篇文章将介绍使用Spring Cloud Gateway实现跨域的方法。 首先,需要在Spring Cloud Gateway中添加Corsconfiguration Bean,代码如下: @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("*")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE")); configuration.setAllowedHeaders(Arrays.asList("Content-Type", "Authorization")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } 然后,在application.yml文件中添加跨域配置,代码如下: spring: cloud: gateway: globalcors: corsConfigurations: '[/**]': allowedOrigins: "*" allowedMethods: - GET - POST - PUT - DELETE allowedHeaders: - "Content-Type" - "Authorization" allowCredentials: true maxAge: 3600 这里设置了允许的来源,方法和头部,还指定了是否允许发送cookie信息,以及最大响应时间。此外,您也可以通过使用代码配置来自定义跨域规则,具体请参考Spring Cloud Gateway官方文档。 最后,在需要进行跨域访问的路由前添加跨域过滤器,代码如下: @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("path_route", r -> r.path("/hello") .filters(f -> f.addRequestHeader("Hello", "World") .addFilter(new CrossOriginFilter())) .uri("http://localhost:8081")) .build(); } 在这个例子中,我们将拦截/hello路由,并添加一个跨域过滤器。 总结来说,使用Spring Cloud Gateway实现跨域需要以下步骤:添加Corsconfiguration Bean,配置application.yml文件,添加跨域过滤器。这样,在微服务架构中实现跨域问题就变得容易了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值