/**
* 跨域允许
*/
@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解决跨域问题的更多相关文章

  1. springCloud项目解决跨域问题

    通过 spring cloud gateway 实现, 方式一:选择在主启动类中注册 CorsWebFilter 类: /** * 1.允许cookies跨域 * 2.允许向该服务器提交请求的URI, ...

  2. JAVA | Java 解决跨域问题

    JAVA | Java 解决跨域问题 Table of Contents 引言 什么是跨域(CORS) 什么情况会跨域 解决方案 前端解决方案 后端解决方案 具体方式 一.使用Filter方式进行设置 ...

  3. AngularJs最简单解决跨域问题案例

    AngularJs最简单解决跨域问题案例 2016-05-20 09:18 82人阅读 评论(0) 收藏 举报  分类: javascript(1)  作者:白狼 出处:http://www.mank ...

  4. 后台访问 JS解决跨域问题

    今天看了看以前做的一个小项目(其实就是一个页面),分享一下当时解决跨域问题的: 背景:公司把项目部署在多台服务器上,防止一台服务器崩溃后,其他的可以继续访问,对应本公司来说,某台服务器出问题后,技术人 ...

  5. PhoneGap开发跨平台移动APP - 解决跨域资源共享

    解决跨域资源共享 一.WebApi解决跨域资源共享. 开发中选择WebApi来作为服务端的数据接口,由于使用PhoneGap,就需要通过js来获取远程远程数据服务器的数据,由于同源策略的限制,这就涉及 ...

  6. 使用nginx解决跨域问题(flask为例)

    背景 我们单位的架构是在api和js之间架构一个中间层(python编写),以实现后端渲染,登录状态判定,跨域转发api等功能.但是这样一个中间会使前端工程师的工作量乘上两倍,原本js可以直接ajax ...

  7. 使用Access-Control-Allow-Origin解决跨域

    什么是跨域 当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如www.google.com),那么我们就可以认为它们是相同的域(协议,域名,端口都必须相同). 跨域就指着 ...

  8. Ajax 是什么?Ajax 的交互模型?同步和异步的区别?如何解决跨域问题?以及 HTTP状态码

    一.Ajax 是什么: 1. 通过异步模式,提升了用户体验 2. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用 3. Ajax 在客户端运行,承担了一部分本来由服务器承担的工作 ...

  9. web api 解决跨域的问题

    web api 总是会遇到跨域的问题,今天我找到了如下方法解决跨域: 1: a:在配置文件中的 加上如下代码 <system.webServer> <httpProtocol> ...

随机推荐

  1. Spring源码之事务(一)— TransactionAutoConfiguration自动配置

    总结: 在ConfigurationClassParser#parse()中会对deferredImportSelectorHandler进行处理(在处理@ComponentScan 自己所写@Com ...

  2. 利用HUtool读取Excel内容

    // 1.获取上传文件输入流 InputStream inputStream = null; try{ inputStream = file.getInputStream(); }catch (Exc ...

  3. Python_PyQt5_打开文件并修改字体

    在同文件夹下新建一个 测试文档.txt  再运行下面代码,可以实现效果 代码 1 #!Python3 2 # -*- coding:utf-8 -*- 3 4 """ 5 ...

  4. [LeetCode题解]142. 环形链表 II | 快慢指针

    解题思路 本题是在141. 环形链表基础上的拓展,如果存在环,要找出环的入口. 如何判断是否存在环,我们知道通过快慢指针,如果相遇就表示有环.那么如何找到入口呢? 如下图所示的链表: 当 fast 与 ...

  5. deepin 安装最新版node

    安装npm sudo apt install npm 安装node sudo npm install -g n 升级node到稳定版 sudo n stable 升级到最新版 sudo n lates ...

  6. 面试官:小伙子,说一说Java多线程有哪些创建方式吧

    第一种 继承Thread类 自定义类,继承Thread类,并重写run()方法. class MyThread1 extends Thread { @Override public void run( ...

  7. ABBYY FineReader 15新增编辑页面布局功能

    ABBYY FineReader 15(Windows系统) 新增编辑页面布局功能,允许用户修改PDF数字文档的页面布局,包括添加或者删除文字段落,文字块以及图片,更改段落,文字块,图片位置.添加或者 ...

  8. jQuery 根据value设置radio默认选中

    jQuery 根据value设置radio默认选中:HTML: <input type="radio" name="type" value="1 ...

  9. leetcode 练习--反转链表

    最近开始学习数据结构和算法的学习,也自然开始在 leetcode 上练习,所以每周大概会分享做过的leetcode 练习,尽量做到每天更新一道题目. 作为 leetcode 练习笔记的第一道题目,选择 ...

  10. 如何测试一个APP

    1.是否支持各种手机系统 2.是否会因为分辨率而出错 3.不同机型能否安装 4.老旧机型 能否通用 5.广告时长 6.测试能否登陆注册 7.卸载时是否会发生意外 8.安装时会不会误认为带病毒 9.用户 ...