@CrossOrigin的作用
简单来说,@CrossOrigin
注解是用来解决浏览器“跨域请求”问题的。
1. 什么是“跨域请求”?
这是一个由浏览器的同源策略引起的安全机制。
同源:指的是两个页面的协议、域名、端口三者完全相同。
跨域:只要协议、域名、端口中有任何一个不同,就是跨域。
例如,你的前端应用跑在 http://localhost:3000
,而后端 API 部署在 http://localhost:8080
。虽然域名都是 localhost
,但端口不同(3000 vs 8080),浏览器就会认为这是跨域请求。
出于安全考虑,浏览器默认会阻止这种跨域请求发出的响应被前端 JavaScript 代码读取(尤其是带有认证信息的请求)。你会在前端控制台看到一个经典的错误:
Access to fetch at 'http://localhost:8080/api/data' from origin 'http://localhost:3000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
2. @CrossOrigin
的作用
@CrossOrigin
注解的作用就是在服务器端告诉浏览器:“我允许来自某个源的跨域请求访问我的资源”。
它会在服务器的 HTTP 响应头中添加一系列以 Access-Control-Allow-*
开头的字段,最主要的是:
Access-Control-Allow-Origin
: 指定允许访问该资源的源(即哪个前端地址是合法的)。*
表示允许任何源。Access-Control-Allow-Methods
: 指定允许的 HTTP 方法(如 GET, POST, PUT 等)。Access-Control-Allow-Headers
: 指定允许的请求头。Access-Control-Allow-Credentials
: 指定是否允许发送 Cookie 等认证信息。
3. 如何使用(在 Spring/Spring Boot 中)
@CrossOrigin
注解非常灵活,可以用在控制器类上(对该类所有方法生效),也可以用在单个方法上。
基本用法:允许所有跨域请求
这是最简单的方式,允许任何来源、任何方法、任何头部的请求。
@RestController
@RequestMapping("/api")
public class MyController {@CrossOrigin(origins = "*") // 允许所有源@GetMapping("/data")public String getData() {return "Hello from server!";}// 或者更简单,不指定任何参数,默认就是允许所有源@CrossOrigin@PostMapping("/submit")public String submitData() {return "Data submitted!";}
}
高级用法:进行精细配置
你可以通过注解的参数进行非常精细的控制。
@CrossOrigin(origins = "https://www.myfrontend.com", // 只允许这个特定的前端地址allowedHeaders = "*", // 允许所有请求头methods = {RequestMethod.GET, RequestMethod.POST}, // 只允许 GET 和 POST 方法allowCredentials = "true", // 允许携带认证信息(如Cookie)maxAge = 3600 // 预检请求结果的缓存时间(秒)
)
@GetMapping("/user")
public User getUser() {// ...
}
全局配置(更推荐的方式)
如果你希望整个项目的所有接口都使用统一的跨域规则,在单个控制器或方法上逐个添加 @CrossOrigin
会很麻烦。这时更推荐使用全局配置。
在 Spring Boot 中,通常通过一个配置类来实现:
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/api/**") // 对所有 /api 开头的接口生效.allowedOrigins("https://www.myfrontend.com", "http://localhost:3000") // 允许的源列表.allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的方法.allowedHeaders("*") // 允许的头部.allowCredentials(true); // 允许认证信息}
}
全局配置的优点是规则统一,易于管理,避免了在无数个控制器里重复注解。
4. 什么时候会触发 CORS 机制?
需要注意的是,CORS 机制对简单请求和非简单请求的处理不同。
简单请求:例如使用 GET、POST(Content-Type 为
application/x-www-form-urlencoded
,multipart/form-data
或text/plain
)等方法。浏览器会直接发出请求,并在响应中检查Access-Control-Allow-Origin
头。非简单请求(或预检请求):例如使用了 PUT、DELETE 方法,或者 Content-Type 是
application/json
。浏览器会先用一个OPTIONS
方法发起一个“预检请求”到服务器,询问是否允许实际请求。服务器必须对 OPTIONS 请求也返回正确的 CORS 头,浏览器确认后才会发出真正的请求。
@CrossOrigin
注解会自动帮你处理这两种情况。
总结
方面 | 解释 |
---|---|
是什么 | 一个 Spring 框架的注解,用于启用和配置 CORS(跨源资源共享)。 |
为什么用 | 解决浏览器同源策略的限制,让不同源的前端应用可以安全地访问后端 API。 |
怎么用 | 1. 局部使用:在 |
核心功能 | 在服务器响应中添加 |
注意:@CrossOrigin
是一个服务器端解决方案。CORS 错误是浏览器的行为,必须在服务器端设置响应头来解除限制。仅仅在前端使用 Ajax 库(如 axios、fetch)是无法解决这个问题的。