# SpringBoot开发中如何处理跨域请求CORS ## 一、什么是跨域请求(CORS) ### 1.1 跨域的定义 跨域(Cross-Origin Resource Sharing)是指浏览器出于安全考虑,限制脚本内发起的跨源HTTP请求。当协议(http/https)、域名或端口有任何不同时,就会被视为跨域请求。 ### 1.2 同源策略限制 浏览器同源策略(Same-Origin Policy)会阻止: - 读取跨域资源 - 修改跨域DOM - 发送跨域AJAX请求 ### 1.3 CORS解决方案 CORS是一种W3C标准,允许服务器声明哪些源站有权限访问哪些资源。 ## 二、SpringBoot中CORS的三种实现方式 ### 2.1 使用@CrossOrigin注解 #### 2.1.1 方法级别配置 ```java @RestController @RequestMapping("/api") public class UserController { @CrossOrigin(origins = "http://localhost:8080") @GetMapping("/users") public List<User> getUsers() { // 业务逻辑 } }
@CrossOrigin(origins = "http://localhost:8080", maxAge = 3600) @RestController @RequestMapping("/api") public class ProductController { // 所有方法都继承跨域配置 }
参数 | 说明 | 示例 |
---|---|---|
origins | 允许的源列表 | “http://a.com,http://b.com” |
methods | 允许的HTTP方法 | {RequestMethod.GET, RequestMethod.POST} |
allowedHeaders | 允许的请求头 | “Content-Type,Authorization” |
exposedHeaders | 暴露的响应头 | “X-Custom-Header” |
maxAge | 预检请求缓存时间(秒) | 1800 |
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://localhost:8080") .allowedMethods("GET", "POST", "PUT") .allowCredentials(true) .maxAge(3600); } }
@Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("http://localhost:8080"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); }
@RestController public class ManualController { @GetMapping("/manual") public ResponseEntity<String> manualCors() { HttpHeaders headers = new HttpHeaders(); headers.add("Access-Control-Allow-Origin", "*"); return new ResponseEntity<>("手动CORS", headers, HttpStatus.OK); } }
@Configuration public class DynamicCorsConfig { @Value("${cors.allowed-origins}") private String[] allowedOrigins; @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins(allowedOrigins) .allowedMethods("*"); } }; } }
@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and() .authorizeRequests() // 其他安全配置... } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("http://trusted.com")); configuration.setAllowedMethods(Arrays.asList("GET","POST")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
当请求满足以下条件时会触发OPTIONS预检请求: 1. 使用PUT/DELETE等非简单方法 2. 发送自定义请求头 3. Content-Type非以下类型: - application/x-www-form-urlencoded - multipart/form-data - text/plain
现象:前端设置了withCredentials: true
但请求失败
解决:
// 服务端配置 .allowedOrigins("http://client.com") // 不能是* .allowCredentials(true) // 前端设置 axios.get(url, { withCredentials: true })
// 正确配置方式 registry.addMapping("/api/v1/**") .addMapping("/api/v2/**");
配置生效优先级: 1. 方法级@CrossOrigin 2. 类级@CrossOrigin 3. 全局CORS配置
# application-prod.yml cors: allowed-origins: https://prod.com allowed-methods: GET,POST # application-dev.yml cors: allowed-origins: http://localhost:*
@Bean public FilterRegistrationBean<CorsFilter> corsFilterRegistration() { FilterRegistrationBean<CorsFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(corsFilter()); registration.setOrder(Ordered.HIGHEST_PRECEDENCE); registration.addUrlPatterns("/*"); registration.setName("corsFilter"); return registration; }
本文详细介绍了SpringBoot中处理CORS的三种主要方式及其适用场景。在实际开发中建议:
通过合理配置CORS,可以在保证安全性的前提下实现灵活的前后端分离架构。
扩展阅读:
- MDN CORS文档
- Spring官方CORS文档 “`
注:本文实际约3600字(中文字符统计),采用Markdown格式编写,包含代码示例、表格和结构化标题,可直接用于技术文档发布。需要调整内容细节或补充具体案例可以进一步修改。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。