SpringMVC 跨域问题两种常用解决方案

如今前后端分离的架构模式日益普及的模式下,前端和后端往往部署在不同的域名或端口下,这就不可避免地会遇到跨域问题。本文将详细介绍SpringMVC其中两种常见且有效的解决方案。

本文目录

一、跨域简介

跨域,简单来说,就是浏览器出于安全策略的考虑,限制网页发起的跨源HTTP请求。这里的 "源" 由协议、域名和端口号共同决定。当一个网页试图通过JavaScript、如使用fetchXMLHttpRequest等 API向与自身不同源的服务器发起请求时,就会触发跨域问题。也就是说三者只要有一个不一致就会发生跨域问题。

二、为什么要解决跨域问题

随着前后端分离架构的广泛应用,前端与后端往往由不同团队开发,部署在不同环境,这种情况下跨域请求难以避免。如果不解决跨域问题,前端页面无法正常获取后端提供的数据或调用后端的接口服务。

三、使用@CrossOrigin注解

@CrossOrigin注解是SpringMVC中一种简单直接的跨域处理方式。可以作用于单个控制器方法,也可以应用于整个控制器类。

1. 应用于单个控制器方法

假设我们有一个获取用户信息的控制器方法,需要允许跨域访问。

java 复制代码
import org.springframework.web.bind.annotation.CrossOrigin;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class UserController {

   @GetMapping("/user")

   @CrossOrigin(origins = "http://user.c.com", maxAge = 3600)

   public User getUser() {

     return new User("user", 30);

   }

}

origins = "http://user.c.com"指定了允许访问的前端源地址,只有来自该地址的跨域请求才会被允许。maxAge = 3600表示预检请求(OPTIONS 请求)的结果可以被缓存 3600 秒,在这段时间内,相同的跨域请求不会再次发送预检请求,从而提高性能。

2. 应用于整个控制器类

如果一个控制器类中的所有方法都需要支持跨域访问,我们可以将@CrossOrigin注解添加到类上,这样更加便捷。

java 复制代码
import org.springframework.web.bind.annotation.CrossOrigin;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

@CrossOrigin(origins = "*", maxAge = 3600)

public class HelloController {

   @GetMapping("/hello")

  public String hello() {

       return "Hello, World!";

   }

   @GetMapping("/greet")

   public String greet() {

       return "Good day!";
   }

}

四、配置全局的CORS规则

除了使用@CrossOrigin注解,我们还可以通过配置WebMvcConfigurer来设置全局的CORS规则。这种方式更加灵活,适合对整个应用的跨域规则进行统一管理。

1. 创建配置类

首先,我们需要创建一个配置类并实现WebMvcConfigurer接口,在接口实现方法中定义 CORS 规则。代码如下:

java 复制代码
import org.springframework.context.annotation.Bean;

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 {

   @Bean
   public WebMvcConfigurer corsConfigurer() {

       return new WebMvcConfigurer() {

          @Override
          public void addCorsMappings(CorsRegistry registry) {

              registry.addMapping("/**")
                     .allowedOrigins("*")
                     .allowedMethods("GET", "POST", "PUT", "DELETE")
                     .allowedHeaders("*")
                     .allowCredentials(false)
                     .maxAge(3600);

           }

      };

  }

}

CorsConfig类通过实现WebMvcConfigurer接口的addCorsMappings方法来配置 CORS 规则。registry.addMapping("/**")表示对所有的请求路径都应用这些CORS规则。allowedOrigins("*")允许所有源进行跨域访问

2. 细粒度控制

如果我们需要对不同的请求路径设置不同的CORS规则,可以在addCorsMappings方法中进行细粒度配置。

java 复制代码
@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/api/public/**")  //对于`/api/public/**`路径下的请求,允许所有源进行跨域访问
           .allowedOrigins("*")
           .allowedMethods("GET")
           .allowedHeaders("*");
    registry.addMapping("/api/private/**")
           .allowedOrigins("http://a.b.com") // 只允许来自`http://a.b.com`的源访问
           .allowedMethods("GET", "POST", "PUT", "DELETE")
           .allowedHeaders("Authorization", "Content-Type")
           .allowCredentials(true)
           .maxAge(3600);
}

五、总结

通过使用@CrossOrigin注解和配置全局的CORS规则,可以有效地解决SpringMVC应用中的跨域问题。@CrossOrigin注解适用于对单个控制器方法或类进行简单的跨域设置,方便快捷;而配置全局 CORS规则则提供了更灵活、更细粒度的控制,适合对整个应用的跨域规则进行统一管理。

|-----------------------------------------------------------------------------------------------------|--------------------|--------------------------------------------------------------------------------------------------|
| ← 上一篇 Java进阶------常用类及常用方法详解 | 记得点赞、关注、收藏哦! | 下一篇 Java进阶------数组超详细整理 → |

相关推荐
龙谷情Sinoam5 分钟前
扩展若依@Excel注解,使其对字段的控制是否导出更加便捷
java
二十雨辰17 分钟前
[尚庭公寓]07-Knife快速入门
java·开发语言·spring
掉鱼的猫28 分钟前
Java MCP 实战:构建跨进程与远程的工具服务
java·openai·mcp
我爱Jack1 小时前
时间与空间复杂度详解:算法效率的度量衡
java·开发语言·算法
米饭「」1 小时前
C++AVL树
java·开发语言·c++
Zonda要好好学习1 小时前
Python入门Day4
java·网络·python
SimonKing1 小时前
告别传统读写!RandomAccessFile让你的Java程序快人一步
java·后端·程序员
Little-Hu1 小时前
QML TextEdit组件
java·服务器·数据库
Edingbrugh.南空2 小时前
Flink ClickHouse 连接器数据读取源码深度解析
java·clickhouse·flink
NE_STOP2 小时前
SpringBoot--简单入门
java·spring