请描述一下如何在SpringBoot项目中实现跨域请求(CORS)的处理?
在Web开发中,出于安全考虑,浏览器通常会阻止一个域的JavaScript代码访问另一个域的资源,这种策略被称为“同源策略”。跨源资源共享(CORS)是一种机制,它允许或拒绝来自不同源的Web页面对服务器资源的请求。在Spring Boot应用中,你可以通过几种方法来处理CORS。
1. 全局CORS配置
你可以通过重写WebMvcConfigurer
的addCorsMappings
方法来实现全局CORS配置。这种方式会应用到你的整个Spring Boot应用。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true);
}
}
在这个配置中,addMapping("/**")
表示对所有的URL都可以进行跨域请求。allowedOrigins
指定了哪些原始域可以访问资源,allowedMethods
指定了允许的HTTP方法,allowedHeaders
允许的头信息,allowCredentials
用于表示是否允许发送Cookie信息。
2. 控制器方法级别的CORS配置
如果你只希望对某些特定的请求处理函数启用CORS,你可以在这些函数上使用@CrossOrigin
注解。
@RestController
@RequestMapping("/api")
public class MyController {
@CrossOrigin(origins = "http://example.com")
@GetMapping("/example")
public String example() {
return "Example";
}
}
在这个例子中,只有/api/example
这个请求支持从http://example.com
发起的跨域请求。
3. 使用@CrossOrigin
注解在类级别上配置CORS
你也可以将@CrossOrigin
注解用在控制器类上,这样该控制器类中的所有请求处理方法都会支持CORS。
@CrossOrigin(origins = "http://example.com", maxAge = 3600)
@RestController
@RequestMapping("/api")
public class MyController {
// ... 省略方法 ...
}
在这个例子中,maxAge
属性定义了预检请求的缓存时间(以秒为单位)。
4. 通过Filter处理CORS
另一种比较底层的方式是创建一个自定义的过滤器,然后在过滤器中设置CORS头。
@Component
public class SimpleCORSFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "http://example.com");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
// ... 省略其他方法 ...
}
在这个自定义Filter
中,我们可以针对进入应用的HTTP请求设置响应头,从而使得特定的域可以接收到响应。
注意
虽然可以通过设置allowedOrigins("*")
来允许所有的域进行跨域请求,但这种做法并不安全,因为它允许任何网站发送请求到你的服务端。在实际生产环境中,建议指定确切的、可信的域名列表,或者使用其他安全策略来限制跨域访问。