Spring: 在SpringBoot项目中解决前端跨域问题

这里写目录标题

  • 一、什么是跨域问题
  • 二、浏览器的同源策略
  • 三、SpringBoot项目中解决跨域问题的5种方式:使用CORS
    • 1、自定 web filter 实现跨域(全局跨域)
    • 2、重写 WebMvcConfigurer(全局跨域)
    • 3、 CorsFilter(全局跨域)
    • 4、使用@CrossOrigin注解 (局部跨域)

一、什么是跨域问题

跨域问题,也称为跨域资源共享(CORS,Cross-Origin Resource Sharing)问题,主要出现在Web开发中,尤其是当前端代码和后端代码分别部署在不同的域名下时。由于浏览器的同源策略限制,一个域的网页中通过JavaScript发起的跨域请求会被浏览器阻止,除非响应报文包含了正确的CORS相关头部信息。

跨域问题主要涉及到以下几个关键点:

  • 同源与跨源:如果两个页面的协议、域名和端口都相同,则它们是同源的;否则,它们是跨源的。

  • 浏览器限制:浏览器默认会阻止跨源请求,除非后端服务器明确允许这种请求。

  • CORS头部:为了允许跨源请求,后端服务器需要在响应中包含特定的CORS头部,如Access-Control-Allow-Origin。

  • 预检请求:对于某些类型的跨域请求(如带有自定义头部的请求或PUT/DELETE等请求),浏览器会先发送一个OPTIONS请求进行预检,以检查服务器是否允许这种请求。

解决跨域问题的方法有多种,包括但不限于:

  • 使用CORS:在后端服务器上配置CORS策略,允许特定的跨源请求。
  • 使用代理服务器:在前端和后端之间设置一个代理服务器,前端请求发送到代理服务器,再由代理服务器转发到后端服务器。
  • JSONP:一种古老的跨域技术,利用<script>标签没有跨域限制的特性来实现跨域请求。但JSONP只支持GET请求,且存在安全隐患,而且前后端都需要写相应的代码。
  • 设置document.domain:对于主域名相同而子域名不同的情况,可以通过设置document.domain来实现跨域。

在实际开发中,应根据具体需求和场景选择合适的跨域解决方案。

二、浏览器的同源策略

同源策略是浏览器的一个安全功能,它阻止从一个源加载的文档或脚本与另一个源的资源进行交互。这是为了防止恶意文档读取或修改另一个源加载的资源。同源策略限制了不同源之间的DOM访问、AJAX请求以及Web存储访问等。当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。此外浏览器是否启用跨域保护机制是又后端的响应Response来决定的
在这里插入图片描述

三、SpringBoot项目中解决跨域问题的5种方式:使用CORS

1、自定 web filter 实现跨域(全局跨域)

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class MyCorsFilter implements Filter {private static Logger LOGGER = LoggerFactory.getLogger(MyCorsFilter.class);@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-Methods", "POST, GET, OPTIONS, DELETE");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Credentials", "true");response.setHeader("Access-Control-Allow-Headers", "*");LOGGER.info("reponse cors: Access-Control-Allow-Origin={}" +", Access-Control-Allow-Methods={}" +", Access-Control-Allow-Credentials={}" +", Access-Control-Allow-Headers={}",response.getHeader("Access-Control-Allow-Origin"),response.getHeader("Access-Control-Allow-Methods"),response.getHeader("Access-Control-Allow-Credentials"),response.getHeader("Access-Control-Allow-Headers"));chain.doFilter(req, res);}
}

2、重写 WebMvcConfigurer(全局跨域)

import org.springframework.context.annotation.Configuration;  
import org.springframework.web.servlet.config.annotation.CorsRegistry;  
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  @Configuration  
public class WebConfig implements WebMvcConfigurer {  @Override  public void addCorsMappings(CorsRegistry registry) {  registry.addMapping("/**") // 允许所有路径  .allowedOrigins("http://example.com") // 允许哪些源的请求  .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的HTTP方法  .allowedHeaders("*") // 允许的头部  .allowCredentials(true) // 是否允许发送cookies  .maxAge(168000); // 预检请求的缓存时间(秒)  }  
}

3、 CorsFilter(全局跨域)

CorsFilter 是 Java Spring 框架中用于处理跨域请求(CORS,Cross-Origin Resource Sharing)的过滤器。通过使用 CorsFilter,你可以配置你的 Spring 应用以允许跨域请求,从而避免浏览器因同源策略而阻止这些请求。下面是一个简单的 Spring Boot 应用中如何使用 CorsFilter 的例子:

  • 添加依赖(如果你使用 Spring Boot,这个依赖可能已经包含在内):
<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-web</artifactId>  
</dependency>
  • 创建 CorsFilter:
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.cors.CorsConfiguration;  
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;  
import org.springframework.web.filter.CorsFilter;  @Configuration  
public class CorsConfig {  @Bean  public CorsFilter corsFilter() {  CorsConfiguration config = new CorsConfiguration();  config.setAllowedOrigins(Arrays.asList("*")); // 允许所有源进行访问  config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE")); // 允许的方法  config.setAllowCredentials(true); // 是否发送cookie  config.setMaxAge(168000); // 预检间隔时间  UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  source.registerCorsConfiguration("/**", config); // 对所有路径应用 CORS 配置  return new CorsFilter(source);  }  
}

在这个例子中,我们创建了一个 CorsFilter Bean,它允许来自任何源的请求,并允许 GET、POST、PUT 和 DELETE 方法。我们还设置了 AllowCredentials 为 true,这意味着浏览器可以发送带有凭据(如 cookies、HTTP 认证及客户端 SSL 证明等)的请求。最后,我们设置了 CORS 预检请求的缓存时间为 168000 秒(即 2 天)。

  • 启动你的 Spring Boot 应用。现在,你的应用应该能够处理跨域请求了。请注意,出于安全考虑,你不应该在生产环境中将 AllowedOrigins 设置为 *,除非你完全信任所有可能的源。通常,你会将 AllowedOrigins 设置为一个特定的域名列表。

4、使用@CrossOrigin注解 (局部跨域)

@CrossOrigin 是 Spring Framework 提供的一个注解,用于解决跨域资源共享(CORS)问题。通过在类或者方法上使用 @CrossOrigin 注解,你可以轻松地为 Spring MVC 控制器开启 CORS 支持。这个注解允许你指定哪些域、HTTP 方法以及头部可以被允许进行跨域请求。

  • 在控制器类上使用
    可以直接在控制器类上使用 @CrossOrigin 注解,以允许整个控制器的所有方法都接受跨域请求:
import org.springframework.web.bind.annotation.CrossOrigin;  
import org.springframework.web.bind.annotation.RestController;  @RestController  
@CrossOrigin(origins = "http://example.com", methods = {RequestMethod.GET, RequestMethod.POST})  
public class MyController {  // ... 控制器方法 ...  
}
  • 在单个方法上使用
    可以将 @CrossOrigin 注解添加到特定的控制器方法上,以仅允许该方法的跨域请求:
import org.springframework.web.bind.annotation.CrossOrigin;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  @RestController  
public class MyController {  @GetMapping("/someMethod")  @CrossOrigin(origins = "http://example.com")  public String someMethod() {  // ... 方法实现 ...  return "Response";  }  
}

使用 @CrossOrigin 注解时,你可以指定多个允许的源,方法,头部等。这提供了一种灵活的方式来控制哪些跨域请求应该被允许。需要注意的是,出于安全考虑,你应该仔细考虑允许哪些源进行跨域请求,并限制允许的 HTTP 方法和头部。

最后,确保你的 Spring Boot 应用已经包含了 Spring Web 的依赖,并且你的控制器类和方法已经正确地映射到了相应的 URL 路径。这样,当来自允许源的请求到达时,Spring MVC 就会自动处理 CORS 预检请求,并在响应中包含正确的 CORS 头部。

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

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

相关文章

社交网络的未来:Facebook如何塑造数字社交的下一章

引言 社交网络已成为我们生活中不可或缺的一部分&#xff0c;而Facebook作为其领军者&#xff0c;一直在塑造着数字社交的未来。本文将深入探讨Facebook在未来如何塑造数字社交的下一章&#xff0c;并对社交网络的发展趋势进行展望和分析。 1. 引领虚拟社交的潮流 Facebook将…

Lombok之@SneakyThrows

1前言&#xff1a; 这里记录一个SneakyThrows的用法&#xff0c;关于他的用法&#xff0c;在官网上可以知道的很清楚 官网介绍&#xff1a;http://projectlombok.org/features/SneakyThrows.html 2代码示例 个人理解&#xff1a;在代码中&#xff0c;使用 try&#xff0c;cat…

C++vector和C语言数组的区别

vector 是 C 标准模板库&#xff08;STL&#xff09;中的一个类模板&#xff0c;它提供了一个动态数组的功能&#xff0c;能够根据需要自动增长或缩小。而 C 语言数组则是 C 语言提供的一种固定大小的序列容器。下面是 vector 和 C 语言数组之间的一些主要区别&#xff1a; 动…

VRP and related algorithms for logistics distribution综述的笔记

选了些自己感兴趣的。 车辆路径问题(VRP)是当今物流公司面临的最关键挑战之一。自1959年丹齐格和兰姆泽(1959年)介绍了卡车调度问题以来,研究人员一直在研究车辆路由和交付调度。它被认为是车辆路径问题(VRP)的范例,并且涉及从中央仓库到地理分散的客户的货物配送。 自…

Polars学习-常用函数代码

下载包 导入包 数据读写 import polars as pl from datetime import datetimedf pl.DataFrame({"integer": [1, 2, 3],"date": [datetime(2022, 1, 1),datetime(2022, 1, 2),datetime(2022, 1, 3),],"float": [4.0, 5.0, 6.0],} ) print(df) …

小白从0学习ctf(web安全)

文章目录 前言一、baby lfi&#xff08;bugku-CTF&#xff09;1、简介2、解题思路1、解题前置知识点2、漏洞利用 二、baby lfi 2&#xff08;bugku-CTF&#xff09;1.解题思路1、漏洞利用 三、lfi&#xff08;bugku CTF&#xff09;1、解题思路1、漏洞利用 总结 前言 此文章是…

uniapp保留两位小数,整数后面加.00

直接把方法粘贴进去就能用 <text class"bold">总收入&#xffe5;{{formater(priceNumer)}}</text>export default {data() {priceNumer: 199.999, // 总收入},methods: {// 保留两位小数formater(data) {if(!data) return 0.00data parseFloat(data).…

SpringBoot -- 整合SpringMVC

SpringBoot已经替我们整合了许多框架并进行了默认的配置&#xff0c;我们只需要在依赖中导入spring-boot-starter-web&#xff0c;就可以直接使用SpringMVC以及web场景下的已经整合好的功能。但SpringBoot的默认配置可能无法满足我们所有的需求&#xff0c;那么我们怎么进行自定…

Java复习第十二天学习笔记(JDBC),附有道云笔记链接

【有道云笔记】十二 3.28 JDBC https://note.youdao.com/s/HsgmqRMw 一、JDBC简介 面向接口编程 在JDBC里面Java这个公司只是提供了一套接口Connection、Statement、ResultSet&#xff0c;每个数据库厂商实现了这套接口&#xff0c;例如MySql公司实现了&#xff1a;MySql驱动…

Unity SqlServer

今天说点废话 这段代码是在Unity中实现的一个简单的数据库连接示例&#xff0c;主要用于演示如何在Unity中使用C#连接到SQL Server数据库并执行基本的SQL查询操作。 导入所需命名空间&#xff1a; 1using UnityEngine; 2using System.Data.SqlClient; UnityEngine是Unity引擎提…

初识 51

keil的使用: 具体细节请移步我上一篇博客:创建第一个51文件-CSDN博客 hex -- 汇编语言实现的文件 -- 直接与单片机对接的文件 单片机 -- 一个集成电脑芯片 单片机开发版 -- 基于单片机的集成电路 stc 89 c52RC / RD 系列单片机 命名规则: 89 -- 版本号&#xff1f; C --…

Dockerfile常用指令以及使用案例

Dockerfile常用指令以及使用案例 1、ADD复制文件 ADD 指令用于复制文件&#xff0c;格式为&#xff1a;* ADD <src>...<dest>* ADD ["<src>",..."<dest>"]从 src 目录复制文件到容器的 dest。其中 src 可以是Dockerfile 所在目录…

C++初阶:string类模拟实现

本节内容主要针对的是在STL之前的string类的实现&#xff0c;通过模拟实现string类的一些功能来更好地使用string。本篇主要针对的是非const对象&#xff0c;如果要实现const的对象的话&#xff0c;只需要在对应的部分增添上const就行了。编者水平有限&#xff0c;如有错误欢迎…

手把手在K210上部署自己在线训练的YOLO模型

小白花了两天时间学习了一下K210&#xff0c;将在线训练的模型部署在K210&#xff08;代码后面给出&#xff09;上&#xff0c;能够识别卡皮巴拉水杯&#xff08;没错&#xff0c;卡皮巴拉&#xff0c;情绪稳定&#xff0c;真的可爱&#xff01;&#xff09;。数据集是用K210拍…

IndexController

目 录 1 IndexController.. 1 1.1 * 后台管理首页... 2 1.2 * 页面跳转... 2 // 取最新的20条日志... 2 1.3 * 个人设置页面... 3 IndexControllerpackage com.my.blog.website.controller.admin;

Java数组填充:Arrays.fill()方法

Arrays.fill()方法 Arrays 类提供了一个 fill() 方法,可以在指定位置进行数值填充。这个方法属于Java标准库中的java.util.Arrays类 1. 方法介绍&#xff1a; 填充到所有位置 Arrays.fill(Type[] array, Type value) 参数&#xff1a; array 是目标数组&#xff0c;可以是…

linux下minio部署和nginx配置

1 下载minio wget https://dl.min.io/server/minio/release/linux-amd64/minio chmod x minio #启动minio&#xff0c;文件数据存放在/data目录 ./minio server /data2 部署minio 下载minio后赋予可执行权限就可以运行了&#xff0c;这里我整理了遇到的坑和解决问题的最终配置…

算法打卡day21(开始回溯)

今日任务&#xff1a; 1&#xff09;77.组合 77.组合 题目链接&#xff1a;77. 组合 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;带你学透回溯算法-组合问题&#xff08;对应力扣题目&#xff1a;77…

Java多线程学习(概念笔记)

面试题&#xff1a;并行和并发有什么区别&#xff1f; 现在都是多核CPU&#xff0c;在多核CPU下 并发是同一时间应对多件事情的能力&#xff0c;多个线程轮流使用一个或多个CPU 并行是同一时间动手做多件事情的能力&#xff0c;4核CPU同时执行4个线程 面试题&#xff1a;创建线…

JavaScript编写评分控件

编写一个评分控件&#xff0c;用一个单行5列的Table做评分控件&#xff0c;监听td的click事件&#xff0c;点击一个td的时候&#xff0c;将这个td及之前的td背景色变为红色&#xff0c;之后的td背景色变为白色。 关键代码&#xff1a; <!DOCTYPE html> <html lang&q…