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

news2024/12/24 22:07:48

问题背景

有个服务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;

  @Bean
  public 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 {
  @Bean
  CorsWebFilter 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, 跨域配置如下

  @Bean
  public WebMvcConfigurer webMvcConfigurer()
  {
    return new WebMvcConfigurer()
    {
      @Override
      public 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.coloradmin.cn/o/868672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android系统-ServiceManager2

目录 引言: 获取ServiceManager 流程图 注册系统服务 获取系统服务 引言: 注册或使用服务之前,需要通过ServiceManager这个DNS来找到对应的服务。那怎么找到ServiceManager呢? 怎么注册系统服务? 怎么获取系统…

分享一组天气组件

先看效果&#xff1a; CSS部分代码&#xff08;查看更多&#xff09;&#xff1a; <style>:root {--bg-color: #E9F5FA;--day-text-color: #4DB0D3;/* 多云 */--cloudy-background: #4DB0D3;--cloudy-temperature: #E6DF95;--cloudy-content: #D3EBF4;/* 晴 */--sunny-b…

Docker高级篇_DockerFile

目录 DockerFile简介构建DockerFile构建过程解析Docker执行Dockerfile的大致流程 DockerFile常用保留字指令FROMMAINTAINERRUNEXPOSEWORKDIRUSERENVVOLUMEADDCOPYCMDENTRYPOINT案例使用虚悬镜像 Docker微服务 DockerFile简介 Dockerfile是用来构建Docker镜像的文本文件&#x…

七、解析应用程序——枚举内容与功能

文章目录 1、web抓取2、发现隐藏内容2.1 蛮力技巧2.2 通过公布的内容进行推测2.3 利用公共信息 3、应用程序页面和功能路径4、发现隐藏参数 攻击应用程序的第一步是收集和分析与其有关的一些关键信息&#xff0c;以清楚了解攻击目标。解析过程首先是枚举应用程序的内容与功能&a…

HTML详解连载(2)

HTML详解连载&#xff08;2&#xff09; 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽超链接作用代码示例解释经验分享 音频标签代码示例注意强调 视频标签代码示例注意强调 列表作用&#xff1a;布局内容排列整齐的区域。分类&#xff1a;无序列表&#x…

基于Googlenet深度学习网络的人员行为动作识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 1. 原理 1.1 深度学习与卷积神经网络&#xff08;CNN&#xff09; 1.2 GoogLeNet 2. 实现过程 2.1 数据预处理 2.2 构建网络模型 2.3 数据输入与训练 2.4 模型评估与调优 3. 应用领域…

Eclipse(STS)Enum 格式化配置

需求 枚举类 的字段&#xff0c;一般长度较小&#xff0c;格式化后&#xff0c;多个字段会变为一行。 需求&#xff1a;希望每个字段独立一行。 格式化后的样式&#xff0c;如下图所示&#xff1a; 配置 1. Windows - Preferences 2. Java-Formatter 如果没有自定义的格…

C++ 循环

有的时候&#xff0c;可能需要多次执行同一块代码。一般情况下&#xff0c;语句是顺序执行的&#xff1a;函数中的第一个语句先执行&#xff0c;接着是第二个语句&#xff0c;依此类推。 编程语言提供了允许更为复杂的执行路径的多种控制结构。 循环语句允许我们多次执行一个…

DVWA暴力破解高级模式宏爆破

先将安全等级调至高级&#xff0c;点击submit提交 浏览器开启bp代理 kali开启bp 工具&#xff0c;开启Proxy 点击Brute Force这个选项卡 bp拦截到请求的数据包 宏设置 如果是有的bp版本比较旧&#xff0c;在旧版本的上面菜单栏有一个Project options点击去选择Session&#xff…

Android系统-进程-Binder1-概述

目录 引言&#xff1a; 一次拷贝 Binder一次通信过程 应用启动中的binder交互 C/S模式&#xff1a; Binder COMMAND BWR数据结构&#xff1a; 引言&#xff1a; Android的binder是从openbinder发展过来的。包括了binder驱动&#xff0c;Native层&#xff0c;Java层。用…

【Matlab智能算法】RBF神经网络-遗传算法(RBF-GA)函数极值寻优——非线性函数求极值

上一篇博客介绍了GRNN-GA&#xff1a;GRNN神经网络遗传算法(GRNN-GA)函数极值寻优——非线性函数求极值&#xff0c;神经网络用的是GRNN神经网络&#xff0c;RBF神经网络&#xff08;径向基函数神经网络&#xff09;和GRNN神经网络有相似之处。本篇博客将GRNN神经网络替换成RBF…

安装istio和部署实例以及仪表盘

安装Istio 接下来我们将介绍如何在 Kubernetes 集群中安装 Istio&#xff0c;这里我们使用的是最新的 1.10.3 版本。 下面的命令可以下载指定的 1.10.3 版本的 Istio: ➜ ~ curl -L https://istio.io/downloadIstio | ISTIO_VERSION1.10.3 sh -如果安装失败&#xff0c;可以…

SolidWorks不能使用选择如允许此选择将生成有冲突的前后关系

SolidWorks不能使用选择如允许此选择将生成有冲突的前后关系 1 SolidWorks不能使用选择如允许此选择将生成有冲突的前后关系 1 SolidWorks不能使用选择如允许此选择将生成有冲突的前后关系 https://www.swrjzxw.com/1556.html SolidWorks装配体时 显示 不能使用选择如允许此选…

Linux 使用gdb调试C程序

一、gdb的一些基础命令 l&#xff1a;显示代码 l n&#xff1a;跳转到当前代码页的第n行的代码 l filename.c &#xff1a;n&#xff1a;跳转到filename.c文件的第n行代码 b 行号&#xff1a;加断点 info break&#xff1a;查看断点信息 delete 断点编号&#xff1a;删除断点 …

力扣 518. 零钱兑换 II

题目来源&#xff1a;https://leetcode.cn/problems/coin-change-ii/description/ C题解&#xff08;来源代码随想录&#xff09;&#xff1a; 这是一道典型的背包问题&#xff0c;一看到钱币数量不限&#xff0c;就知道这是一个完全背包。但本题和纯完全背包不一样&#xff0c…

天津大数据培训机构哪家好?大数据必备知识

随着我国互联网IT行业的发展&#xff0c;我们步入了大数据时代&#xff0c;现在市场上急需大量的大数据专业人才&#xff0c;发展空间大&#xff0c;从业范围广&#xff0c;学习大数据专业对未来还是很有帮助的。今天小编来带大家了解一下大数据的知识和学习方式&#xff0c;作…

Pygame 入门教程

1. Pygame简介 Pygame是一个基于Python的游戏开发库&#xff0c;它提供了一系列的工具和接口&#xff0c;使开发人员能够轻松地创建各种类型的游戏&#xff0c;包括2D游戏和简单的3D游戏。 在开始学习Pygame之前&#xff0c;您需要先安装Pygame库。您可以通过以下命令在命令行…

分布式定时任务系列5:XXL-job中blockingQueue的应用

传送门 分布式定时任务系列1&#xff1a;XXL-job安装 分布式定时任务系列2&#xff1a;XXL-job使用 分布式定时任务系列3&#xff1a;任务执行引擎设计 分布式定时任务系列4&#xff1a;任务执行引擎设计续 Java并发编程实战1&#xff1a;java中的阻塞队列 引子 这篇文章的…

linux下查看谁在用显卡

一般查看显卡的使用情况使用的命令为 nvidia-smi但是这个只能输出显卡的占用及进程&#xff0c;看不到谁在用 信息如下 但是可以借助上面的PID信息&#xff0c;查看对应的进程是谁调用的&#xff0c; 命令为&#xff1a; ps -f -p 4417其中4417就是上图中的其中一个PID 输出…

snapshotter not loaded: overlayfs: invalid argument

测试containerd是否能创建和启动成功 执行如下命令拉取镜像并创建容器&#xff1a; 拉取容器 ctr i pull docker.io/library/nginx:alpine 创建容器 ctr c create --net-host docker.io/library/nginx:alpine nginx ctr task start -d nginx查看Containerd服务启动信息&…