Spring Boot 解决跨域问题

1,432 阅读3分钟

在 Spring Boot 中,跨域(CORS,Cross-Origin Resource Sharing)问题通常发生在前端(如 Vue、React)请求后端 API 时,因 同源策略 限制,导致浏览器拒绝跨域请求。

  1. 解决跨域的方式

Spring Boot 提供多种方法来解决跨域问题,包括:

  1. 使用 @CrossOrigin 注解(局部配置)
  2. 使用 WebMvcConfigurer 进行全局配置
  3. 使用 CorsFilter 进行全局配置
  4. 使用 Nginx 代理(非 Spring Boot 方案)

方法 1:使用 @CrossOrigin 注解(局部跨域)

如果你只想对某个 Controller 或方法 允许跨域,可以使用 @CrossOrigin 注解。

示例

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://localhost:3000") // 允许 http://localhost:3000 访问
public class MyController {
    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

📌 说明

  • @CrossOrigin(origins = "``http://localhost:3000``") 只允许 http://localhost:3000 访问该控制器的所有方法。
  • 也可以加在具体的方法上,只允许部分 API 跨域。

限制

  • 只能针对特定控制器或方法,不能全局生效。
  • 适用于小型项目或单个 API 的跨域需求。

方法 2:全局配置 WebMvcConfigurer

如果你希望全局允许跨域,而不是在每个控制器都加 @CrossOrigin,可以使用 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 CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")  // 允许所有路径
                        .allowedOrigins("http://localhost:3000")  // 允许的来源(可修改为前端地址)
                        .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方法
                        .allowedHeaders("*") // 允许所有请求头
                        .allowCredentials(true); // 允许携带 Cookie
            }
        };
    }
}

📌 说明

  • addMapping("/**"):表示所有路径都允许跨域。
  • allowedOrigins("``http://localhost:3000``"):指定允许访问的前端地址。
  • allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS"):允许的 HTTP 方法。
  • allowedHeaders("*"):允许所有请求头。
  • allowCredentials(true):允许跨域请求携带 cookies

适用场景

  • 适用于 大部分 Spring Boot 项目,特别是前后端分离的情况。
  • 推荐方式,因为它配置灵活、易维护。

方法 3:使用 CorsFilter 进行全局跨域配置

如果你想完全控制跨域策略,可以使用 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;
import java.util.Arrays;
@Configuration
public class CustomCorsFilter {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Arrays.asList("http://localhost:3000")); // 允许的前端地址
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 允许的 HTTP 方法
        config.setAllowedHeaders(Arrays.asList("*")); // 允许所有请求头
        config.setAllowCredentials(true); // 允许携带 Cookie
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config); // 应用于所有接口
        return new CorsFilter(source);
    }
}

📌 说明

  • CorsFilter 方式比 WebMvcConfigurer 更底层,适用于更复杂的跨域配置需求。
  • 适用于 Spring Security 开启时,因为 WebMvcConfigurer 可能会被 Spring Security 拦截。

适用场景

  • 适用于 Spring Security 开启时WebMvcConfigurer 可能失效的情况。
  • 适用于 更灵活的跨域控制需求

方法 4:Nginx 代理(非 Spring Boot 方案)

如果你的 Spring Boot 部署在后端,并且前端有独立的服务器(如 Nginx),可以用 Nginx 代理 来处理跨域。

Nginx 配置

server {
    listen 80;
    server_name api.example.com;
    location / {
        proxy_pass http://localhost:8080;  # 代理到 Spring Boot
        add_header Access-Control-Allow-Origin 
;  add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" ; *        add_header Access-Control-Allow-Headers "*
";
        add_header Access-Control-Allow-Credentials true;
    }
}

📌 说明

  • proxy_pass http://localhost:8080;:代理到 Spring Boot 服务器。
  • add_header Access-Control-Allow-Origin *;:允许所有来源访问。
  • add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";:允许的请求方法。
  • add_header Access-Control-Allow-Credentials true;:允许携带 Cookie。

适用场景

  • 生产环境推荐,特别是使用 Nginx 作为反向代理时。
  • 不会影响 Spring Boot 代码,对性能也更友好。

结论

  • 小项目或临时跨域@CrossOrigin
  • 全局跨域WebMvcConfigurer(推荐)
  • Spring Security 项目CorsFilter
  • 生产环境(Nginx 代理) → 让 Nginx 处理跨域