gpt4 book ai didi

spring cloud gateway跨域全局CORS配置方式

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 25 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章spring cloud gateway跨域全局CORS配置方式由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

在Spring 5 Webflux中,配置CORS,可以通过自定义WebFilter实现:

注:此种写法需真实跨域访问,监控header中才会带相应属性.

代码实现方式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.http.HttpMethod;
import reactor.core.publisher.Mono;
 
import static org.springframework.web.cors.CorsConfiguration.ALL;
public class XXXApplication{
public static void main(String[] args) {
     SpringApplication.run(XXXApplication. class , args);
}
private static final String MAX_AGE = "18000L" ;
@Bean
public WebFilter corsFilter() {
     return (ServerWebExchange ctx, WebFilterChain chain) -> {
         ServerHttpRequest request = ctx.getRequest();
         if (!CorsUtils.isCorsRequest(request)) {
             return chain.filter(ctx);
         }
         HttpHeaders requestHeaders = request.getHeaders();
         ServerHttpResponse response = ctx.getResponse();
         HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();
         HttpHeaders headers = response.getHeaders();
         headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());
         headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());
         if (requestMethod != null ) {
             headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());
         }
         headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true" );
         headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, ALL);
         headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
         if (request.getMethod() == HttpMethod.OPTIONS) {
             response.setStatusCode(HttpStatus.OK);
             return Mono.empty();
         }
         return chain.filter(ctx);
     };
}
}

配置实现方式

网上还提到一种配置写法,实测好用:

?
1
2
3
4
5
6
7
8
9
spring:
   cloud:
     gateway:
       globalcors:
         corsConfigurations:
           '[/**]' :
             allowedOrigins: "*"
             allowedMethods: "*"
             allowedHeaders: "*"

springcloud gateway 跨域的解决

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

验证

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

1、gateway跨域配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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请求时没有返回跨域信息 。

2、zuul网关或者其它微服务servlet

向容器中注入跨域过滤器 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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、实现一个过滤器,来做跨域允许

需要在响应头中加入以下信息 。

?
1
2
3
4
5
# 这个为请求头中的 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' ;

3、采用nginx做代理,配置跨域响应头。(强烈推荐)

请求先到nginx,nginx再去请求gateway, 由nginx添加跨域响应头 。

?
1
2
3
4
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中方案,测试完美解决! 。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.

原文链接:https://wanghq.blog.csdn.net/article/details/88179626 。

最后此篇关于spring cloud gateway跨域全局CORS配置方式的文章就讲到这里了,如果你想了解更多关于spring cloud gateway跨域全局CORS配置方式的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com