Spring Boot 中如何解决跨域问题

在现代的 web 应用中,前端和后端往往是分开的,前端可能托管在不同的服务器上。当前端通过 AJAX 请求与后端进行通信时,浏览器出于安全考虑,会限制不同源之间的请求。这种机制被称为同源策略(Same-Origin Policy),而跨源资源共享(CORS,Cross-Origin Resource Sharing)便是为了解决这一问题。本文将探讨如何在 Spring Boot 中解决跨域问题。

什么是 CORS?

CORS 是一种浏览器机制,它允许服务器声明哪些外部域可以访问其资源。通过在响应头中添加特定信息,服务器能够告诉浏览器是否允许所请求的资源跨域。

Spring Boot 解决跨域问题的基本方法

在 Spring Boot 中,可以通过几种方式配置 CORS 的支持。以下是几种常见的方法:

  1. 使用 @CrossOrigin 注解
  2. WebMvcConfigurer 中配置全局 CORS
  3. 使用 Filter 配置

1. 使用 @CrossOrigin 注解

这是最简单的方法,对于单个 Controller 或方法,可以使用 @CrossOrigin 注解,指定允许跨域请求的源。

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

@RestController
@CrossOrigin(origins = "http://localhost:3000")  // 允许来自指定源的请求
public class MyController {

    @GetMapping("/api/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

2. 在 WebMvcConfigurer 中配置全局 CORS

如果你希望对整个应用程序或多个 Controller 进行通用 CORS 配置,可以实现 WebMvcConfigurer 接口。

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 WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 允许所有路径
                .allowedOrigins("http://localhost:3000")  // 允许来自指定源的请求
                .allowedMethods("GET", "POST", "PUT", "DELETE"); // 允许的HTTP方法
    }
}

3. 使用 Filter 配置

Filter 是另一种能处理跨域请求的方式,适合需要复杂配置的场景,例如动态配置 CORS。

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 java.io.IOException;

public class SimpleCORSFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        chain.doFilter(req, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}
}

状态图

在解决跨域问题的过程中,我们的应用程序的状态图如下所示:

stateDiagram
    state跨域请求 {
        [*] --> 请求发起
        请求发起 --> 服务端处理
        服务端处理 --> 返回响应
        返回响应 --> [*]
    }

关系图

我们可以用关系图表示跨域请求的关系,如下:

erDiagram
    FRONTEND {
        string domain
        string name
    }
    
    BACKEND {
        string domain
        string name
    }
    
    FRONTEND ||--o{ BACKEND : "发送请求"

结论

通过上述方法,我们可以在 Spring Boot 中轻松地配置 CORS,解决前后端分离时常见的跨域问题。无论是使用简单的 @CrossOrigin 注解,还是在全局级别上进行配置,都能有效地实现跨域请求的管理。在开发现代 web 应用时,理解 CORS 的机制以及如何解决跨域问题对于提供良好的用户体验和系统安全性都是至关重要的。希望本文能为你在使用 Spring Boot 时处理跨域问题提供一些实用的参考与帮助。