SpringCloudGateway配置跨域设置以及如何本地测试跨域

问题背景

有个服务A ,自身对外提供服务,几个系统的前端页面也在调用,使用springboot 2.6.8开发的,自身因为有前端直接调用已经配置了跨域。

现在有网关服务,一部分前端通过网关访问服务A(因为之前没有网关服务,这里不解释为何以前没有,总之大家在工作中会遇到各种各项的系统设计 或者部署 或者使用的hack, 老旧系统又不能随便改动,主要涉及的使用方较多,很难协调他们统一改动)。 网关使用的SpringCloudGateway ( 实际的gateway版本是3.1.3 webflux 2.7.8), 网络服务也配置跨域,但是一些系统的前端通过网关调用A的时候包跨域有问题。

前端浏览器中错误信息, 这里省略其他无关域名和ip内容,只保留错误的主要信息

Access-Control-Allow-Origin’ header contains multiple values’, but only one is allowed 

简要分析

两个服务都已经配置了跨域,直接访问网关自身的一些API (例如health check的api)都正常,但是通过网关访问服务A就有问题, 一看是因为两个都配置了跨域,直接取消服务A的跨域配置,错误会消息,但是因为一部分前端是直接调用A服务的,因为A服务自身的跨域设置不能取消。 只能在网关处更改。 最终就是将网关处从A返回的response header进行去重,满足需求。

解决办法

在gateway配置的RouteLocator修改如下, 备注:也可以通过配置文件实现,本人采用代码的方式。 这是可以工作的示例代码,其中svcaBaseUrl,serverPort需要再配置文件中对应的值,这两个也是A服务的域名, 以及网关服务的端口。

备注:其他人也遇到同样问题, 参看:https://stackoverflow.com/questions/70983244/use-spring-gateway-and-getting-error-access-control-allow-origin-header-conta。 本文方法仅供参考

@Component
public class MyRouteLocator
{@Value("${svca.baseUrl}")String svcaBaseUrl;@Value("${server.port}")int serverPort;@Beanpublic RouteLocator myRoutes(RouteLocatorBuilder builder){return builder.routes().route(p -> p.path("/proxy/version/query-by-id", "/proxy/version/status", "/health","/proxy/version/add",).filters(f ->  f.stripPrefix(1).dedupeResponseHeader("Access-Control-Allow-Origin", RETAIN_UNIQUE.name())).uri(svcaBaseUrl)).route(p -> p.path("/proxy/version/*","/proxy/log/*").filters(f ->  f.stripPrefix(1)).uri("http://127.0.0.1:%d/notSupport".formatted(serverPort))).build();}
}

网关跨域配置 MyConfig.java, 备注:这只是全局配置跨域一种方式,可以在api单独配置。此处不在赘述。可以参考其他网络如何给springboot程序配置跨域设置。

package x.y.proxy;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.cors.reactive.UrlBasedCorsConfigurationSource;@Configuration
public class MyConfig {@BeanCorsWebFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.setAllowCredentials(true);config.addAllowedOriginPattern("*");config.addAllowedHeader("*");config.addAllowedMethod("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}}

服务A是springboot 2.6.8, 跨域配置如下

  @Beanpublic WebMvcConfigurer webMvcConfigurer(){return new WebMvcConfigurer(){@Overridepublic void addCorsMappings(CorsRegistry registry){registry.addMapping("/**") .allowedOriginPatterns("*") .allowedHeaders("*") .allowedMethods("*") .allowCredentials(true) .maxAge(TimeUnit.DAYS.toSeconds(1));}};}

本地浏览器中验证跨域问题

跨域问题是前端发现的,后端开发可以在chrome浏览器中直接测试验证,不需要前端同学配置,可以加速开发过程

//  测试post方法使用 a.b.c是需要替换的域名 或者ip
:var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://a.b.c/version/add?Id=2&label=test1');
xhr.setRequestHeader("Content-type","application/json;charset=UTF-8");
xhr.setRequestHeader("jwt-token","JhbGciOiJSUzI1N");
xhr.setRequestHeader("x-access-token","aaa");
xhr.send('{"version": "1.0","desc": "string"}');
xhr.onload = function(e) {var xhr = e.target;console.log(xhr.responseText);
}//  测试get方法使用 a.b.c是需要替换的域名 或者ip
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://a.b.c/common/health');
xhr.setRequestHeader("x-access-token","aaa");
xhr.setRequestHeader("Access-Control-Allow-Origin","bbb");
xhr.setRequestHeader("Content-type","application/json;charset=UTF-8");
xhr.send(null);
xhr.onload = function(e) {var xhr = e.target;console.log(xhr.responseText);
}

执行console测试示意图

在这里插入图片描述

备注:这里附录上网关工程的一些gradle信息,如果你使用的gateway版本与我不一样,请以对应版本的官方文档为准

例如我使用gateway 3.1.3 cors配置文件如下:
https://docs.spring.io/spring-cloud-gateway/docs/3.1.3/reference/html/#cors-configuration

plugins {id 'java'id 'org.springframework.boot' version '2.7.8'id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}group = 'com.x.y'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'configurations {compileOnly {extendsFrom annotationProcessor}
}repositories {mavenCentral()
}ext {set('springCloudVersion', "2021.0.3")
}dependencies {implementation 'org.springframework.boot:spring-boot-starter-webflux'implementation 'org.springframework.cloud:spring-cloud-starter-gateway'implementation 'org.springdoc:springdoc-openapi-ui:1.6.11'implementation 'io.netty:netty-all:4.1.75.Final'compileOnly 'org.projectlombok:lombok'annotationProcessor 'org.projectlombok:lombok'testImplementation 'org.springframework.boot:spring-boot-starter-test'testImplementation 'io.projectreactor:reactor-test'
}dependencyManagement {imports {mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"}
}tasks.named('test') {useJUnitPlatform()
}
bootJar {archiveBaseName = 'app'def excludes = [~"junit.*\\.jar", ~"hamcrest.*\\.jar"]exclude {for (exclude in excludes) {if (it.name ==~ exclude) {return true}}return false}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/63739.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP Fiori 将GUI中的自开发报表添加到Fiori 工作台

1. 首先我们在workbench 中开发一个GUI report 这里我们开发的是一个简单的物料清单报表 2. 分配一个事务代码。 注意这里的SAP GUI for HTML 要打上勾 3. 创建语义对象( Create Semantic Object) 事物代码: path: SAP NetWeaver ->…

SpringBoot案例-部门管理-修改

目录 前言 查看页面原型,明确需求 页面原型 需求 阅读接口文件 思路分析 功能接口开发 控制层(Controller类) 业务层(Service类) 业务类 业务实现类 持久层(Mapper类) 接口测试 前…

mac安装open3d时候出现错误

在测试open3d是否正常顺利安装时&#xff0c;出现了如下错误&#xff1a; python -c "import open3d as o3d; print(o3d.__version__)" Traceback (most recent call last):File "<string>", line 1, in <module>File "/Users/huangzhe/…

Spring5 AOP 默认使用 JDK

这是博主在使用dubbo实现远程过程调用的时候遇到的问题&#xff1a; 我们如果在服务提供者类上加入Transactional事务控制注解后&#xff0c;服务就发布不成功了。原因是事务控制的底层原理是为服务提供者类创建代理对象&#xff0c;而默认情况下Spring是基于JDK动态代理方式创…

包装类+初识泛型

目录 1 .包装类 1.1 基本数据类型对应的包装类 1.2.1装箱 ​1.2.2拆箱 2.初识泛型 2.1什么是泛型 2.2泛型类 2.3裸类型 2.4泛型的上界 2.5泛型方法 1 .包装类 基本数据类型所对应的类类型 在 Java 中&#xff0c;由于基本类型不是继承自 Object &#xff0c;为了在泛型…

Spring Boot集成Mybatis Plus通过Pagehelper实现分页查询

文章目录 0 简要说明Pagehelper1 搭建环境1.1 项目目录1.2 项目搭建需要的依赖1.3 配置分页插件拦截器1.4 源代码启动类实体类数据层xml映射文件业务层业务层实现类控制层接口配置swagger请求体 2 可能出现的疑问或者问题2.1 关于total属性疑问2.2 分页不生效问题 3 案例说明3.…

分类预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据分类预测

分类预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据分类预测 目录 分类预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据分类预测效果一览基本介绍研究内容程序设计参考资料 效果一览 基本介绍 Matlab实现基于…

【Docker晋升记】No.2 --- Docker工具安装使用、命令行选项及构建、共享和运行容器化应用程序

文章目录 前言&#x1f31f;一、Docker工具安装&#x1f31f;二、Docker命令行选项&#x1f30f;2.1.docker run命令选项&#xff1a;&#x1f30f;2.2.docker build命令选项&#xff1a;&#x1f30f;2.3.docker images命令选项&#xff1a;&#x1f30f;2.4.docker ps命令选项…

多线程与高并发--------阻塞队列

四、阻塞队列 一、基础概念 1.1 生产者消费者概念 生产者消费者是设计模式的一种。让生产者和消费者基于一个容器来解决强耦合问题。 生产者 消费者彼此之间不会直接通讯的&#xff0c;而是通过一个容器&#xff08;队列&#xff09;进行通讯。 所以生产者生产完数据后扔到…

matlab使用教程(14)—稀疏矩阵的运算

1.运算效率 1.1计算复杂度 稀疏运算的计算复杂度与矩阵中的非零元素数 nnz 成比例。计算复杂度在线性上还与矩阵的行大小 m 和列大小 n 相关&#xff0c;但与积 m*n&#xff08;零元素和非零元素总数&#xff09;无关。相当复杂的运算&#xff08;例如对稀疏线性方程求解&…

RabbitMQ 事务

事务简介 就像我们了解的MySQL中的事务一样&#xff0c;RabbiMQ的事务也具备原子性和一致性&#xff0c;并且RabbiMQ的事务是针对消息从生产者发送到RabbitMQ中提供的支持&#xff0c;因此不同事务可以同时给同一个队列发送信息。   可通过channel.txSelect&#xff0c;chann…

Android侧滑栏(一)可缩放可一起移动的侧滑栏

在实际的各类App开发中&#xff0c;经常会需要做一个左侧的侧滑栏&#xff0c;类似于QQ这种。 今天这篇文章总结下自己在开发中遇到的这类可以跟随移动且可以缩放的侧滑栏。 一、实现原理 使用 HorizontalScrollView 实现一个水平方向的可滑动的View&#xff0c;左布局为侧滑…