Skip to content

跨域资源共享 (CORS)

由于安全原因,浏览器禁止 AJAX 调用当前源之外的资源。Spring MVC 提供了灵活的机制来处理跨域资源共享(CORS)。

核心概念

CORS 允许你指定哪些跨域请求是被授权的。它比传统的 IFRAME 或 JSONP 方案更安全、更强大。

启用方式

1. 使用 @CrossOrigin 注解

你可以将 @CrossOrigin 注解用于控制器类或具体的方法上。

java
@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin(origins = "https://domain2.com")
    @GetMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }
}
kotlin
@RestController
@RequestMapping("/account")
class AccountController {

    @CrossOrigin(origins = ["https://domain2.com"])
    @GetMapping("/{id}")
    fun retrieve(@PathVariable id: Long): Account {
        // ...
    }
}

默认行为

  • 允许所有源(Origins)。
  • 允许所有标头(Headers)。
  • 允许控制器映射的所有 HTTP 方法。
  • maxAge 默认为 30 分钟。

2. 全局配置

如果你需要为整个应用配置 CORS,可以实现 WebMvcConfigurer 接口。

java
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("https://domain1.com")
            .allowedMethods("GET", "POST", "PUT", "DELETE")
            .allowCredentials(true)
            .maxAge(3600);
    }
}

3. CORS 过滤器 (CorsFilter)

如果你使用了 Spring Security,建议通过 Spring Security 的 内置支持 来处理 CORS。否则,你可以注册 CorsFilter


补充教学

1. 预检请求 (Preflight Request)

对于“非简单请求”(如带有自定义 Header 或使用 PUT/DELETE 方法的请求),浏览器会先发送一个 OPTIONS 动作的请求进行探测,询问服务器是否允许跨域。 Spring MVC 的 HandlerMapping 会自动处理这些预检请求并返回对应的 CORS 响应头,而不会触发实际的业务逻辑。

2. 带有凭据的请求 (Credentialed Requests)

如果跨域请求需要携带 Cookie,必须:

  1. 设置 allowCredentials(true)
  2. 注意:此时 allowedOrigins 不能设置为通配符 *,必须指定明确的域名。

3. 配置叠加规则

Spring MVC 支持全局配置与局部配置共存:

  • Origins / Methods / Headers:采取并集规则(全局定义的和局部定义的都会生效)。
  • allowCredentials / maxAge:采取覆盖规则(局部配置会覆盖全局配置)。

Based on Spring Framework.