springcloud gateway解决跨域问题
/**
* 跨域允许
*/
@Configuration
public class CorsConfig { @Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = ctx.getResponse();
HttpHeaders headers = response.getHeaders();
headers.set(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "3600");
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(ctx);
};
}
}
参考博客:https://blog.csdn.net/a294634473/article/details/90715903
以上只是简单的处理,如果再网关和后端都进行了跨域配置,在返回的请求头中可能包含多个跨域的信息,那样同样会让请求出现异常,所以在上面的处理后,要将重复的跨域头信息给删除掉
在高一点的springcloud gateway中包含了DedupeResponseHeaderGatewayFilterFactory,可以进行过滤,如果低版本,没有这个类,自行从高版本中拷贝过来作为一个实现类,然后添加上配置
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin Access-Control-Allow-Methods Access-Control-Allow-Headers Vary
附件代码:
GwCorsFilter.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.util.pattern.PathPatternParser; @Configuration
public class GwCorsFilter { @Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 允许cookies跨域
config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
config.addAllowedMethod("*");// 允许提交请求的方法类型,*表示全部允许
config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了 org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource source =
new org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config); return new CorsWebFilter(source);
}
}
DedupeResponseHeaderGatewayFilterFactory.java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors; import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.web.server.ServerWebExchange; import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono; /*
Use case: Both your legacy backend and your API gateway add CORS header values. So, your consumer ends up with
Access-Control-Allow-Credentials: true, true
Access-Control-Allow-Origin: https://musk.mars, https://musk.mars
(The one from the gateway will be the first of the two.) To fix, add
DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin Configuration parameters:
- name
String representing response header names, space separated. Required.
- strategy
RETAIN_FIRST - Default. Retain the first value only.
RETAIN_LAST - Retain the last value only.
RETAIN_UNIQUE - Retain all unique values in the order of their first encounter. Example 1
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Response header Access-Control-Allow-Credentials: true, false
Modified response header Access-Control-Allow-Credentials: true Example 2
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_LAST Response header Access-Control-Allow-Credentials: true, false
Modified response header Access-Control-Allow-Credentials: false Example 3
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_UNIQUE Response header Access-Control-Allow-Credentials: true, true
Modified response header Access-Control-Allow-Credentials: true
*/ /**
* @author Vitaliy Pavlyuk
*/
@Slf4j
public class DedupeResponseHeaderGatewayFilterFactory extends
AbstractGatewayFilterFactory<DedupeResponseHeaderGatewayFilterFactory.Config> { private static final String STRATEGY_KEY = "strategy"; public DedupeResponseHeaderGatewayFilterFactory() {
super(Config.class);
} @Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(NAME_KEY, STRATEGY_KEY);
} @Override
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(
() -> dedupe(exchange.getResponse().getHeaders(), config)));
}
};
} public enum Strategy { /**
* Default: Retain the first value only.
*/
RETAIN_FIRST, /**
* Retain the last value only.
*/
RETAIN_LAST, /**
* Retain all unique values in the order of their first encounter.
*/
RETAIN_UNIQUE } void dedupe(HttpHeaders headers, Config config) {
String names = config.getName();
Strategy strategy = config.getStrategy();
if (headers == null || names == null || strategy == null) {
return;
}
for (String name : names.split(" ")) {
dedupe(headers, name.trim(), strategy);
}
} private void dedupe(HttpHeaders headers, String name, Strategy strategy) {
List<String> values = headers.get(name);
log.info("{}={}",name,values);
if (values == null || values.size() <= 1) {
return;
}
switch (strategy) {
case RETAIN_FIRST:
headers.set(name, values.get(0));
break;
case RETAIN_LAST:
headers.set(name, values.get(values.size() - 1));
break;
case RETAIN_UNIQUE:
headers.put(name, values.stream().distinct().collect(Collectors.toList()));
break;
default:
break;
}
} public static class Config extends AbstractGatewayFilterFactory.NameConfig { private Strategy strategy = Strategy.RETAIN_FIRST; public Strategy getStrategy() {
return strategy;
} public Config setStrategy(Strategy strategy) {
this.strategy = strategy;
return this;
} } }
springcloud gateway解决跨域问题的更多相关文章
- springCloud项目解决跨域问题
通过 spring cloud gateway 实现, 方式一:选择在主启动类中注册 CorsWebFilter 类: /** * 1.允许cookies跨域 * 2.允许向该服务器提交请求的URI, ...
- JAVA | Java 解决跨域问题
JAVA | Java 解决跨域问题 Table of Contents 引言 什么是跨域(CORS) 什么情况会跨域 解决方案 前端解决方案 后端解决方案 具体方式 一.使用Filter方式进行设置 ...
- AngularJs最简单解决跨域问题案例
AngularJs最简单解决跨域问题案例 2016-05-20 09:18 82人阅读 评论(0) 收藏 举报 分类: javascript(1) 作者:白狼 出处:http://www.mank ...
- 后台访问 JS解决跨域问题
今天看了看以前做的一个小项目(其实就是一个页面),分享一下当时解决跨域问题的: 背景:公司把项目部署在多台服务器上,防止一台服务器崩溃后,其他的可以继续访问,对应本公司来说,某台服务器出问题后,技术人 ...
- PhoneGap开发跨平台移动APP - 解决跨域资源共享
解决跨域资源共享 一.WebApi解决跨域资源共享. 开发中选择WebApi来作为服务端的数据接口,由于使用PhoneGap,就需要通过js来获取远程远程数据服务器的数据,由于同源策略的限制,这就涉及 ...
- 使用nginx解决跨域问题(flask为例)
背景 我们单位的架构是在api和js之间架构一个中间层(python编写),以实现后端渲染,登录状态判定,跨域转发api等功能.但是这样一个中间会使前端工程师的工作量乘上两倍,原本js可以直接ajax ...
- 使用Access-Control-Allow-Origin解决跨域
什么是跨域 当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如www.google.com),那么我们就可以认为它们是相同的域(协议,域名,端口都必须相同). 跨域就指着 ...
- Ajax 是什么?Ajax 的交互模型?同步和异步的区别?如何解决跨域问题?以及 HTTP状态码
一.Ajax 是什么: 1. 通过异步模式,提升了用户体验 2. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用 3. Ajax 在客户端运行,承担了一部分本来由服务器承担的工作 ...
- web api 解决跨域的问题
web api 总是会遇到跨域的问题,今天我找到了如下方法解决跨域: 1: a:在配置文件中的 加上如下代码 <system.webServer> <httpProtocol> ...
随机推荐
- 熬夜肝出5大点,18张图带你彻底弄懂MySQL事务日志
在当今社会,充斥着大量的数据.从众多APP上的账户资料到银行信用体系等个人档案,都离不开对大量数据的组织.存储和管理.而这,便是数据库存在的目的和价值.目前数据库的类型主要分为两种,一种是关系型数据库 ...
- 三:redis启动后的基础知识
Redis启动后的杂项基础知识 1.单进进程 单进程模型来处理客户端的请求.对读写等事件的响应是通过对epoll函数的包装来做到的.Redis的实际处理速度完全依靠主进程的执行效率 Epo ...
- WIN10下安装python3.7.2出现“尝试创建C:\Users\XX\AppData\Roaming\Microsoft\Installer时出错”
WIN10下安装python3.7.2出现"尝试创建C:\Users\XX\AppData\Roaming\Microsoft\Installer时出错" 1.右键点击安装包以管理 ...
- SQL Server 常用近百条SQL语句(收藏版)
1. sqlserver查看实例级别的信息,使用SERVERPROPERTY函数 select SERVERPROPERTY ('propertyname') 2. 查看实例级别的某个参数XX的配置 ...
- [LeetCode题解]109. 有序链表转换二叉搜索树 | 快慢指针 + 递归
题目描述 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定的有序链表: ...
- 让面试官心服口服:Thread.sleep、synchronized、LockSupport.park的线程阻塞有何区别?
前言 在日常编码的过程中,我们经常会使用Thread.sleep.LockSupport.park()主动阻塞线程,或者使用synchronized和Object.wait来阻塞线程保证并发安全.此时 ...
- zabbix地图显示全国延迟
Zabbix 地图显示全国延迟 1. 效果图 2. 实现方法 将地图.png上传到zabbix为背景,上传红绿点.png为图标.然后新建主机关联模板为ICMP Ping,新建一个拓扑图调用地图为背 ...
- Django踩坑记录2
错误如下 OperationalError no such table 解决方法: 首先执行: python manage.py makemigrations 再执行 python manage.py ...
- FL Studio——电音编曲人的奠基石
随着近年来摇滚.电音的发展,越来越多的人开始对电子音乐编曲感兴趣,而电音编曲的首要条件,就是需要一个好的DAW(数字音频工作站),常用的DAW有很多,例如Cubase.Nuendo.Pro Tools ...
- 【mq读书笔记】消息消费队列和索引文件的更新
ConsumeQueue,IndexFile需要及时更新,否则无法及时被消费,根据消息属性查找消息也会出现较大延迟. mq通过开启一个线程ReputMessageService来准时转发commitL ...