网站首页 > 精选教程 正文
你是否也曾遇到过这样的场景?前端页面请求后端API,却突然弹出“跨域请求被拒绝”的警告,让人一头雾水又束手无策?你是否在为 Spring Boot 应用中的跨域问题而烦恼呢?别担心,今天我们就来为你揭开 Spring Boot 解决跨域问题的神秘面纱,带你掌握SpringBoot解决跨域问题的终极秘籍,让你的前后端交互畅通无阻!
让我们揭开跨域问题的神秘面纱。跨域,简单来说,就是浏览器出于安全考虑,实施了同源策略,限制了一个网页中的脚本只能与同源网址下的资源进行交互。同源指的是协议、域名、端口三者都相同。一旦这些条件不满足,就会发生跨域问题。
在现代的 Web 开发中,特别是现在是前后端分离的时代,前端页面请求后端的API接口时,跨域问题常常让我们的前后端开发者们头疼不已。当你的前端应用和后端服务部署在不同的域名或端口上时,浏览器的同源策略就会阻止它们之间的通信。这就像是一道无形的墙,阻碍了你的应用发挥出最大的潜力。
但是,别害怕!Spring Boot 为我们提供了多种强大的方式来为我们解决跨域问题。现在就让我们一起来看看它们是如何实现的吧!
一、使用@CrossOrigin注解
这是一种非常简单直接的方式。你只需要在控制器类或方法上添加@CrossOrigin注解,就可以轻松解决跨域问题。
实现步骤:
- 在需要处理跨域的控制器类上添加注解,比如:
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.CrossOrigin;
// 标注为 RESTful 风格的控制器
@RestController
// 允许跨域访问
@CrossOrigin
public class MyController {
// 控制器方法
}
- 也可以在特定的方法上添加,例如:
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.CrossOrigin;
// 标注为 RESTful 风格的控制器
@RestController
public class MyController {
// 处理 POST 请求的映射
@PostMapping("/myendpoint")
// 允许指定源的跨域访问
@CrossOrigin(origins = "http://your-client-url.com")
public String myMethod() {
return "Response";
}
}
优点:简单方便,无需额外的配置类,可针对特定方法进行跨域配置。
缺点:如果有多个控制器需要处理跨域,需要在每个地方添加注解,比较繁琐。
二、实现WebMvcConfigurer接口
通过创建一个配置类并实现WebMvcConfigurer接口,重写addCorsMappings方法,我们可以集中进行跨域配置。
实现步骤:
- 创建一个配置类:
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 CorsConfig implements WebMvcConfigurer {
// 重写 addCorsMappings 方法进行跨域配置
@Override
public void addCorsMappings(CorsRegistry registry) {
// 添加跨域映射,对所有路径生效
registry.addMapping("/**")
// 允许指定源的跨域访问
.allowedOrigins("http://your-client-url.com")
// 允许的 HTTP 方法
.allowedMethods("GET", "POST", "PUT", "DELETE")
// 允许的请求头
.allowedHeaders("*")
// 是否允许携带凭证(如 Cookie)
.allowCredentials(true);
}
}
优点:可以统一处理整个应用的跨域需求,可定制性高。
缺点:需要创建一个额外的配置类,对于小型项目可能有点复杂。
三、使用过滤器(Filter)
创建一个自定义过滤器实现javax.servlet.Filter接口,能够完全控制对请求和响应的处理。
实现步骤:
- 创建过滤器类:
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CorsFilter implements Filter {
// 过滤器初始化方法
@Override
public void init(FilterConfig filterConfig) {}
// 过滤请求的主要方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 将 ServletRequest 转换为 HttpServletRequest
HttpServletRequest request = (HttpServletRequest) servletRequest;
// 将 ServletResponse 转换为 HttpServletResponse
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 设置允许的源
response.setHeader("Access-Control-Allow-Origin", "http://your-client-url.com");
// 设置允许的 HTTP 方法
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
// 设置允许的请求头
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
// 设置是否允许携带凭证
response.setHeader("Access-Control-Allow-Credentials", "true");
// 如果是预检请求(OPTIONS 方法),直接返回成功状态
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
// 继续执行请求链
filterChain.doFilter(request, response);
}
}
// 过滤器销毁方法
@Override
public void destroy() {}
}
- 在配置类中注册过滤器:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
// 创建过滤器注册 Bean
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
// 设置过滤器实例
registrationBean.setFilter(new CorsFilter());
// 添加过滤的 URL 模式
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
优点:高度灵活,可深度定制跨域处理。
缺点:代码量较多,过滤器的注册和配置相对复杂。
四、使用全局配置文件(application.properties 或 application.yml)
在配置文件中添加相应属性来配置跨域。
在application.properties中:
spring.web.resources.add-mappings=false
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
spring.web.servlet.mvc.method.annotation.cors-mappings=mapping: /**
allowed-origins: http://your-client-url.com
allowed-methods: GET,POST,PUT,DELETE
allowed-headers: *
allow-credentials: true
在application.yml中:
spring:
web:
resources:
add-mappings: false
servlet:
mvc:
method:
annotation:
cors-mappings:
mapping: /**
allowed-origins: http://your-client-url.com
allowed-methods: GET,POST,PUT,DELETE
allowed-headers: *
allow-credentials: true
优点:配置简单,无需编写代码,对不熟悉代码配置的开发者友好。
缺点:可定制性相对较低,无法满足复杂的跨域需求。
五、使用 Spring Security 解决跨域
如果项目中使用了 Spring Security,可以在配置类中这样处理跨域:
实现步骤:
- 创建配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;
// 标注为配置类并启用 Web 安全
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// 创建安全过滤器链 Bean
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 配置跨域和禁用 CSRF(跨站请求伪造)保护
http
.cors().and()
.csrf().disable();
return http.build();
}
// 创建允许 URL 编码斜杠的 HTTP 防火墙 Bean
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
return new DefaultHttpFirewall();
}
}
优点:在安全框架内统一处理跨域问题,可与其他安全配置结合。
缺点:需要对 Spring Security 有一定了解,配置相对复杂。
六、使用 Nginx 反向代理
Nginx 以其高性能和灵活的配置而备受青睐。通过将前端请求先发送到 Nginx,再由 Nginx 转发到后端 Spring Boot 应用,可以轻松解决跨域问题。
实现步骤:
- 安装和配置 Nginx:首先需要安装 Nginx,然后在 Nginx 的配置文件中进行跨域配置。例如,可以在nginx.conf文件中添加以下内容:
server {
listen 80;
server_name your_domain_name;
location / {
proxy_pass http://your_backend_url;
add_header 'Access-Control-Allow-Origin' 'http://your-client-url.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
}
}
- 启动 Nginx:配置完成后,启动 Nginx 服务。
优点:
- 高性能,能处理大量并发请求。
- 集中配置,便于管理多个应用的跨域规则。
- 可进行复杂的请求路由和过滤。
- 缓存静态资源,提高响应速度。
- 实现负载均衡。
缺点:
- 需要额外部署和配置 Nginx,学习成本高。
- 维护成本较高,配置变化需重新部署和测试。
- 可能引入新的故障点。
七、使用 Spring Cloud Gateway 解决跨域
Spring Cloud Gateway 是一个基于 Spring Boot 和 Spring WebFlux 的 API 网关,可以在网关层处理跨域问题。
实现步骤:
- 添加依赖:
在项目的pom.xml文件中添加spring-cloud-starter-gateway依赖。 - 配置网关:
在application.yml文件中进行如下配置:
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "http://your-client-url.com"
allowedMethods:
- GET
- POST
- PUT
- DELETE
allowedHeaders: "*"
allowCredentials: true
优点:
- 集中在网关层处理跨域,无需在每个服务中单独处理。
- 可以利用网关的其他功能,如路由、限流等。
缺点:
- 需要引入额外的组件(Spring Cloud Gateway),增加了系统的复杂性。
- 对于不熟悉网关的开发者来说,学习成本较高。
八、使用 Zuul 解决跨域
Zuul 是 Netflix 开源的微服务网关,也可以用来处理跨域问题。
实现步骤:
- 添加依赖:
在项目的pom.xml文件中添加spring-cloud-starter-netflix-zuul依赖。 - 配置 Zuul:
在application.yml文件中进行如下配置:
zuul:
routes:
your-service-id:
path: /your-service-path/**
url: http://your-service-url
cors:
allowed-origins: "http://your-client-url.com"
allowed-methods: "GET,POST,PUT,DELETE"
allowed-headers: "*"
allow-credentials: true
优点:
- 可以在网关层统一处理跨域问题。
- 与 Spring Cloud 生态系统集成良好。
缺点:
- Zuul 1.x 基于 Servlet,性能相对较低;Zuul 2.x 虽然性能有所提升,但使用相对较少。
- 同样需要引入额外的组件,增加系统复杂性。
跨域问题虽然让开发者头疼不已,但通过上述终极秘籍,你完全可以轻松应对。无论是快速简便的局部跨域,还是一劳永逸的全局配置,亦或是灵活强大的自定义CORS处理,总有一款适合你。赶快动手实践吧,让你的SpringBoot项目更加健壮、高效!
猜你喜欢
- 2025-06-04 我的世界光影MOD下载(我的世界光影mod下载安装)
- 2025-06-04 我的世界1.7/1.8VoxelMap小地图MOD下载
- 2025-06-04 我的世界1.7.10多世界 整合包(我的世界1.7.10forge整合包)
- 2025-06-04 我的世界1.8最好用的修改器下载(我的世界1.8最好用的修改器下载安装)
- 2025-06-04 我的世界更多弯曲动作MOD下载(我的世界更多弯曲动作mod下载手机版)
- 2025-06-04 我的世界龙珠MOD下载(我的世界龙珠模组整合包下载)
- 2025-06-04 我的世界1.7.10以太2 下载(我的世界以太2mod1.12.2)
- 2025-06-04 我的世界虚拟人生MOD下载分享(我的世界虚拟人生下载安装)
- 2025-06-04 我的世界无正版账号的简单联机方法(非网易版,仅适用于局域网)
- 2025-06-04 “我的语言极限,即是我的世界的极限。” ——《On Java》书籍推荐
你 发表评论:
欢迎- 最近发表
-
- 我的世界光影MOD下载(我的世界光影mod下载安装)
- 我的世界1.7/1.8VoxelMap小地图MOD下载
- 我的世界1.7.10多世界 整合包(我的世界1.7.10forge整合包)
- 我的世界1.8最好用的修改器下载(我的世界1.8最好用的修改器下载安装)
- 我的世界更多弯曲动作MOD下载(我的世界更多弯曲动作mod下载手机版)
- 我的世界龙珠MOD下载(我的世界龙珠模组整合包下载)
- 我的世界1.7.10以太2 下载(我的世界以太2mod1.12.2)
- 我的世界虚拟人生MOD下载分享(我的世界虚拟人生下载安装)
- 我的世界无正版账号的简单联机方法(非网易版,仅适用于局域网)
- “我的语言极限,即是我的世界的极限。” ——《On Java》书籍推荐
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)