当前位置: 首页 > news >正文

SpringBoot 项目中后端实现跨域的5种方式!!!

文章目录

  • SpringBoot 项目中后端实现跨域的5种方式!!!
    • 一、为什么会出现跨域问题
    • 二、什么是跨域
    • 三、非同源限制
    • 四、Java后端 实现 CORS 跨域请求的方式
      • 1、返回新的 CorsFilter(全局跨域)
      • 2、重写 WebMvcConfigurer(全局跨域)
      • 3、使用注解 (局部跨域)
      • 4、手动设置响应头(局部跨域)
      • 5、使用自定义filter实现跨域

SpringBoot 项目中后端实现跨域的5种方式!!!

一、为什么会出现跨域问题

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略
同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

二、什么是跨域

举例说明:

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
在这里插入图片描述

三、非同源限制

【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

【2】无法接触非同源网页的 DOM

【3】无法向非同源地址发送 AJAX 请求

四、Java后端 实现 CORS 跨域请求的方式

对于 CORS的跨域请求,主要有以下几种方式可供选择:

1、返回新的CorsFilter
2、重写 WebMvcConfigurer
3、使用注解 @CrossOrigin
4、手动设置响应头 (HttpServletResponse)
5、自定web filter 实现跨域
注意

  • CorFilter / WebMvConfigurer / @CrossOrigin 需要 SpringMVC 4.2以上版本才支持,对应springBoot 1.3版本以上
  • 上面前两种方式属于全局 CORS 配置,后两种属于局部 CORS配置。如果使用了局部跨域是会覆盖全局跨域的规则,所以可以通过 @CrossOrigin 注解来进行细粒度更高的跨域资源控制。
  • 其实无论哪种方案,最终目的都是修改响应头,向响应头中添加浏览器所要求的数据,进而实现跨域

1、返回新的 CorsFilter(全局跨域)

在任意配置类,返回一个 新的 CorsFIlter Bean ,并添加映射路径和具体的CORS配置路径。

@Configuration
public class GlobalCorsConfig {@Beanpublic CorsFilter corsFilter() {//1. 添加 CORS配置信息CorsConfiguration config = new CorsConfiguration();//放行哪些原始域config.addAllowedOrigin("*");//是否发送 Cookieconfig.setAllowCredentials(true);//放行哪些请求方式config.addAllowedMethod("*");//放行哪些原始请求头部信息config.addAllowedHeader("*");//暴露哪些头部信息config.addExposedHeader("*");//2. 添加映射路径UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();corsConfigurationSource.registerCorsConfiguration("/**",config);//3. 返回新的CorsFilterreturn new CorsFilter(corsConfigurationSource);}
}

2、重写 WebMvcConfigurer(全局跨域)

@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")//是否发送Cookie.allowCredentials(true)//放行哪些原始域.allowedOrigins("*").allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"}).allowedHeaders("*").exposedHeaders("*");}
}

3、使用注解 (局部跨域)

在控制器(类上)上使用注解 @CrossOrigin:,表示该类的所有方法允许跨域。

@RestController
@CrossOrigin(origins = "*")
public class HelloController {@RequestMapping("/hello")public String hello() {return "hello world";}
}

在方法上使用注解 @CrossOrigin:

@RequestMapping("/hello")@CrossOrigin(origins = "*")//@CrossOrigin(value = "http://localhost:8081") //指定具体ip允许跨域public String hello() {return "hello world";}

4、手动设置响应头(局部跨域)

使用 HttpServletResponse 对象添加响应头(Access-Control-Allow-Origin)来授权原始域,这里 Origin的值也可以设置为 “*”,表示全部放行。

@RequestMapping("/index")
public String index(HttpServletResponse response) {response.addHeader("Access-Allow-Control-Origin","*");return "index";
}

5、使用自定义filter实现跨域

ssm的写法
首先编写一个过滤器,可以起名字为MyCorsFilter.java

package cn.fpl.aop;import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
@Component
public class MyCorsFilter implements Filter {public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) res;response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");chain.doFilter(req, res);}public void init(FilterConfig filterConfig) {}public void destroy() {}
}

在web.xml中配置这个过滤器,使其生效

<!-- 跨域访问 START-->
<filter><filter-name>CorsFilter</filter-name><filter-class>cn.fpl.aop.MyCorsFilter</filter-class>
</filter>
<filter-mapping><filter-name>CorsFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 跨域访问 END  -->

springboot可以简化

import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "CorsFilter ")
@Configuration
public class CorsFilter implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) res;response.setHeader("Access-Control-Allow-Origin","*");response.setHeader("Access-Control-Allow-Credentials", "true");response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");chain.doFilter(req, res);}
}

相关文章:

SpringBoot 项目中后端实现跨域的5种方式!!!

文章目录 SpringBoot 项目中后端实现跨域的5种方式&#xff01;&#xff01;&#xff01;一、为什么会出现跨域问题二、什么是跨域三、非同源限制四、Java后端 实现 CORS 跨域请求的方式1、返回新的 CorsFilter(全局跨域)2、重写 WebMvcConfigurer(全局跨域)3、使用注解 (局部跨…...

Vue3前端开发,provide和enject的基础练习,跨层级传递数据

Vue3前端开发,provide和enject的基础练习,跨层级传递数据&#xff01; 声明:provide虽然可以跨层级传递&#xff0c;但是依旧是需要由上向下的方向传递。根传子的方向。 <script setup> import {onMounted, ref} from vue import Base from ./components/Base.vue impor…...

Python 循环结构值while循环

while循环是一种常用的循环结构&#xff0c;它会在满足特定条件的情况下重复执行一段代码块。 基本语法&#xff1a; while condition:# 循环体代码while循环的执行过程如下&#xff1a; 首先&#xff0c;判断循环条件condition&#xff08;布尔表达式&#xff09;是否为真。…...

MSSQL-识别扩展extended event(扩展事件)中的时间单位

经常使用sqlserver extended event(扩展事件)&#xff0c;但是总是忘记扩展事件使用的时间单位&#xff0c;不确定它们是 秒、毫秒、还是微秒&#xff1f; 以下下代码能够从 相关DMV中提取description字段内容来识别时间单位&#xff1a; SELECT [p].[name] [package_name],[o…...

vue3中l和vue2中v-model不同点

vue2比较让人诟病的一点就是提供了两种双向绑定&#xff1a;v-model和.sync&#xff0c; 在vue3中&#xff0c;去掉了.sync修饰符&#xff0c;只需要使用v-model进行双向绑定即可。 为了让v-model更好的针对多个属性进行双向绑定&#xff08;vue2中自定义组件中v-model只能使用…...

使用 Swift 代码优化项目编译速度

引言 软件的性能是评价一个软件质量的重要指标&#xff0c;尤其在今天这个时代&#xff0c;性能已成为大型项目不可或缺的考虑因素之一。对于用户量极大的软件&#xff0c;如网银系统、在线购物商城等&#xff0c;更是必须保证其高效稳定的性能。在这种背景下&#xff0c;优化…...

基于springboot+vue的社区团购系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…...

three.js从入门到精通系列教程002 - three.js正交相机OrthographicCamera

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>three.js从入门到精通系列教程002 - three.js正交相机OrthographicCamera</title><script src"ThreeJS/three.js"></script><script src&qu…...

Golang 搭建 WebSocket 应用(七) - 性能、可用性

在前面的文章中&#xff0c;提到过非功能性需求决定了架构。 今天我们再来考虑一下另外两个非功能性需求&#xff1a;性能和可用性。 前言 关于性能&#xff0c;其实并不是只有我们这个消息推送系统独有的问题。 对于所有的开发者而言&#xff0c;都多多少少会处理过性能相关…...

Qt 状态机框架:The State Machine Framework (一)

传送门: Qt 状态机框架:The State Machine Framework (一) Qt 状态机框架:The State Machine Framework (二) 一、什么是状态机框架 状态机框架提供了用于创建和执行状态图/表[1]的类。这些概念和表示法基于Harel的Statecharts:一种复杂系统的可视化形式,也是UML状态图的基…...

高通平台学习一

什么是QMI? Qualcom Message Interface 高通信息接口 高通平台目前都是非对称多核心&#xff0c;最主要的是AP和Modem。两个处理器怎么进行通信呢&#xff0c;我们把AP和Modem当作两个主机&#xff0c;问题就变得了很简单&#xff0c;TCP/IP协议不是一种非常成功的进程间跨主…...

Python爬虫时被封IP,该怎么解决?四大动态IP平台测评

在使用 Python 进行爬虫时&#xff0c;很有可能因为一些异常行为被封 IP&#xff0c;这主要是因为一些爬虫时产生的异常行为导致的。 在曾经的一次数据爬取的时候&#xff0c;我尝试去爬取Google地图上面的商家联系方式和地址信息做营销&#xff0c;可是很不幸&#xff0c;还只…...

积分梳状滤波器CIC原理与实现

CIC&#xff08;Cascade Intergrator Comb&#xff09;&#xff1a;级联积分梳状滤波器&#xff0c;是由积分器和梳状滤波器级联而得。滤波器系数为1&#xff0c;无需对系数进行存储&#xff0c;只有加法器、积分器和寄存器&#xff0c;资源消耗少&#xff0c;运算速率高&#…...

【项目管理】CMMI-原因分析与解决过程(CAR)

概述&#xff1a; “原因分析与解决”通过预防缺陷或者问题的引入以及识别并适当纳入优秀过程性能的原因&#xff0c;改进质量与生产率。 目录 1、文档结构 2、原因分析与解决过程域包括如下活动 3、选择需要加以分析的结果(启动条件) 4、过程活动与实践对照表 5、实例 1、…...

【设计模式】文件目录管理是组合模式吗?

组合模式是什么&#xff1f; 组合模式是一种将对象组合成树形结构以表示"部分-整体"的层次结构的设计模式。它使得用户对单个对象和组合对象的使用具有一致性。 组合模式在什么情况下使用&#xff1f; 当你发现你需要在代码中实现树形数据结构&#xff0c;让整体-部…...

利用appium自动控制移动设备并提取数据

安装appium-python-client模块并启动已安装好的环境 安装appium-python-client模块 在window的虚拟环境下执行pip install appium-python-client 启动夜神模拟器&#xff0c;进入夜神模拟器所在的安装路径的bin目录下&#xff0c;进入cmd终端&#xff0c;使用adb命令建立adb…...

day22_236二叉树最近公共祖先_235二叉搜索树(最近公共祖先_701插入一个节点_450删除一个节点)

文章目录 [236 二叉树的最近公共祖先](https://programmercarl.com/0236.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE)[235 二叉搜索树的最近公共祖先](https://program…...

OpenSource - 工具管理器easy-manager-tool

文章目录 功能说明运行配置环境配置启动docker部署 项目安全UI展示 Easy-Manager-Tool 打造软件行业首款集成工具&#xff0c;不管你是程序员&#xff0c;测试&#xff0c;运维等都可以使用该软件来提升自己的工作效率。 Easy-Manager-Tool 的诞生是为了解决软件行业众多参与者…...

Laravel7 + easyWeChat 实现微信公众号支付功能

注册服务号&#xff0c;需进行微信认证&#xff0c;此时需缴费 300 元/年&#xff0c;必须是认证成功的服务号才能开通微信支付。 注册微信支付商户号 1、登录 https://pay.weixin.qq.com/index.php/core/home/login?return_urlhttps%3A%2F%2Fpay.weixin.qq.com%2Findex.php%…...

Linux环境下,针对QT软件工程搭建C++Test单元测试环境的操作指南

文章目录 前言一、安装QT二、安装CTest三、使用QT生成.bdf文件四、创建CTest工程注意事项 前言 CTest是Parasoft公司出品的一款可以针对C/C源代码进行静态分析、单元测试、集成测试的测试工具。本文主要讲解如何在Linux环境下&#xff0c;搭建QT插件版的CTest测试环境。 一、…...

16k+ start 一个开源的的监控系统部署教程

安装条件 Linux或macOS系统 4GB内存 开放 33014、33174、3183端口 1.安装 1、下载源码 首先使用 git 克隆源码到本地 git clone -b main https://github.com/SigNoz/signoz.git && cd signoz/deploy/ 方式1&#xff1a;运行 install.sh 脚本一键安装 ./install.s…...

Mermaid使用教程(绘制各种图)

Mermaid使用教程&#xff08;绘制各种图&#xff09; 文章目录 Mermaid使用教程&#xff08;绘制各种图&#xff09;简介饼状图简单的例子应用案例 序列图简单案例应用案例另一个应用案例 甘特图简单案例应用案例一个更为复杂的应用案例 Git图简单案例 总结 简介 本文将主要介…...

OpenAI/ChatGPT Plus 支持的虚拟卡有哪些

最近&#xff0c;有关 OpenAI/ChatGPT Plus 需要信用卡的讨论越来越多。在这篇文章中&#xff0c;我将分享一些我在绑定信用卡过程中得到的经验和教训&#xff0c;以及 OpenAI/ChatGPT Plus 支持的卡类型。 不支持的卡 根据 OpenAI 的地区限制&#xff0c;国内和香港的卡都不…...

ARM多核调度器DSU

1. 背景 从A75开始&#xff0c;ARM提出了一个新的多核心管理系统单元&#xff0c;叫做DSU(DynamIQ Shared Unit)。DSU的核心功能是控制CPU内核&#xff0c;使其成簇Cluster使用&#xff0c;簇内每一个核心可以单独开关、调整频率/电压&#xff0c;能效表现更佳&#xff0c;甚至…...

vue解决部署文件缓存方式

问题&#xff1a;系统上线后&#xff0c;除了bug。紧急修复后&#xff0c;发现安卓正常&#xff0c;ios上海市有问题。通过debug后发现&#xff0c;ios上缓存严重。于是想到了打包文件加时间戳的方式来去除缓存。 vue2 配置打包输出文件名方式&#xff1a; const baseUrl &qu…...

游戏开发中的噪声算法

一、噪声 噪声是游戏编程的常见技术&#xff0c;广泛应用于地形生成&#xff0c;图形学等多方面。 那么为什么要引入噪声这个概念呢&#xff1f;在程序中&#xff0c;我们经常使用直接使用最简单的rand()生成随机值&#xff0c;但它的问题在于生成的随机值太“随机”了&#xf…...

CodeReview 小工具

大家开发中有没有遇到一个版本开发的非常杂&#xff0c;开发很多个项目&#xff0c;改动几周后甚至已经忘了自己改了些什么&#xff0c;领导要对代码review的时候&#xff0c;理不清楚自己改过的代码&#xff0c;只能将主要改动的大功能过一遍。这样就很容易造成review遗漏&…...

UE5 C++ Slate独立程序的打包方法

在源码版安装目录内找到已编译通过的xxx.exe&#xff0c;&#xff08;\Engine\Binaries\Win64\xxx.exe)&#xff0c;在需要的位置新建文件夹&#xff0c;拷贝源码版Engine内的Binaries、Content、Shaders文件夹到目标文件夹内&#xff0c;将xxx.exe放入对应位置&#xff0c;删除…...

探索设计模式的魅力:一篇文章让你彻底搞懂建造者模式

建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;旨在将一个复杂对象的创建过程与其表示分离&#xff0c;使得同样的构建过程可以创建不同的表示形式。 主要角色&#xff1a; 产品&#xff08;Product&#xff09;&#xff1a;表示正在构建…...

Facebook广告投放指南,如何运营多个Facebook广告账户不被封?

许多卖家做广告投放会选择 Facebook 作为主要的业务和产品推广平台。然而&#xff0c;要在这个竞争激烈的平台上脱颖而出并成功拓宽广告覆盖面并不容易&#xff0c;通常情况下大家会运营多个Facebook广告账号&#xff0c;但是很多人因此遭遇Facebook账号被封的情况&#xff0c;…...