spring cloud gateway跨域全局CORS配置方式
作者:草宝虫 时间:2021-11-02 01:09:00
在Spring 5 Webflux中,配置CORS,可以通过自定义WebFilter实现:
注:此种写法需真实跨域访问,监控header中才会带相应属性。
代码实现方式
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);
};
}
}
配置实现方式
网上还提到一种配置写法,实测好用:
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowedHeaders: "*"
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请求时没有返回跨域信息
2、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' ;
3、采用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中方案,测试完美解决!
来源:https://wanghq.blog.csdn.net/article/details/88179626
标签:spring,cloud,gateway,跨域,CORS
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
jar包运行时提示jar中没有主清单属性的解决
2023-11-23 19:04:10
![](https://img.aspxhome.com/file/2023/2/59532_0s.png)
Android如何让WebView中的HTML5页面实现视频全屏播放
2023-07-29 00:32:06
![](https://img.aspxhome.com/file/2023/1/82401_0s.jpg)
java如何获得redis所有的key-value
2022-03-13 12:22:14
![](https://img.aspxhome.com/file/2023/3/60823_0s.jpg)
轻松理解Java面试和开发中的IoC(控制反转)
2023-08-10 03:00:35
![](https://img.aspxhome.com/file/2023/4/58184_0s.jpg)
C#判断一天、一年已经过了百分之多少的方法
2022-07-16 15:23:11
![](https://img.aspxhome.com/file/2023/0/68660_0s.png)
MyBatis中的模糊查询语句
2022-09-30 03:36:59
Maven配置文件pom.xml详解
2022-07-03 02:26:43
SpringBoot JdbcTemplate批量操作的示例代码
2023-05-15 21:46:42
java中匿名内部类详解
2022-10-06 14:56:56
spring解决循环依赖的方案示例
2021-11-19 03:31:04
![](https://img.aspxhome.com/file/2023/8/68018_0s.png)
浅谈Java消息队列总结篇(ActiveMQ、RabbitMQ、ZeroMQ、Kafka)
2022-06-13 01:30:40
![](https://img.aspxhome.com/file/2023/8/60698_0s.jpg)
Redis集群与SSM整合使用方法
2023-07-02 02:17:05
![](https://img.aspxhome.com/file/2023/0/67180_0s.png)
IntelliJ IDEA 2020.2正式发布,两点多多总能助你提效
2023-08-30 18:15:18
![](https://img.aspxhome.com/file/2023/2/58082_0s.jpg)
java json 省市级联实例代码
2021-11-13 18:50:35
Java8通过Function获取字段名的步骤
2022-07-14 14:06:23
Java实现在PPT中创建SmartArt图形的示例代码
2022-01-16 06:22:52
![](https://img.aspxhome.com/file/2023/3/62343_0s.jpg)
JAVA SFTP文件上传、下载及批量下载实例
2023-02-11 14:31:46
Javaweb开发中通过Servlet生成验证码图片
2022-06-23 06:33:34
![](https://img.aspxhome.com/file/2023/2/60992_0s.png)
java程序员常见的sql错误
2021-11-06 22:24:14
![](https://img.aspxhome.com/file/2023/5/68535_0s.jpg)
java实战之飞机大战小游戏(源码加注释)
2021-08-01 17:46:08
![](https://img.aspxhome.com/file/2023/5/63485_0s.png)