跨域资源共享 (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,必须:
- 设置
allowCredentials(true)。 - 注意:此时
allowedOrigins不能设置为通配符*,必须指定明确的域名。
3. 配置叠加规则
Spring MVC 支持全局配置与局部配置共存:
- Origins / Methods / Headers:采取并集规则(全局定义的和局部定义的都会生效)。
- allowCredentials / maxAge:采取覆盖规则(局部配置会覆盖全局配置)。