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进阶------数组超详细整理 → |

相关推荐
珹洺1 小时前
JSP技术入门指南【一】利用IDEA从零开始搭建你的第一个JSP系统
java·开发语言·前端·html·intellij-idea·jsp
User_芊芊君子2 小时前
跨平台开发选Java还是C?应用场景与性能深度对比
java·c语言·开发语言
寻梦人121382 小时前
关于在Spring Boot + SpringSecurity工程中Sercurity上下文对象无法传递至新线程的问题解决
java·spring boot·后端
一只小松许️3 小时前
Rust泛型与特性
java·开发语言·rust
angushine8 小时前
Gateway获取下游最终响应码
java·开发语言·gateway
爱的叹息8 小时前
关于 JDK 中的 jce.jar 的详解,以及与之功能类似的主流加解密工具的详细对比分析
java·python·jar
一一Null8 小时前
Token安全存储的几种方式
android·java·安全·android studio
AUGENSTERN_dc8 小时前
RaabitMQ 快速入门
java·后端·rabbitmq
晓纪同学8 小时前
C++ Primer (第五版)-第十三章 拷贝控制
java·开发语言·c++