拦截器实现CORS
通过自定义拦截器实现CORS,可以灵活控制跨域策略。
拦截器实现方案
创建CorsInterceptor
Java
@Component
public class CorsInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String origin = request.getHeader("Origin");
// 设置允许的源
if (isValidOrigin(origin)) {
response.setHeader("Access-Control-Allow-Origin", origin);
}
// 设置允许的方法
response.setHeader("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS");
// 设置允许的请求头
response.setHeader("Access-Control-Allow-Headers",
"Content-Type, Authorization, X-Requested-With");
// 允许携带凭证
response.setHeader("Access-Control-Allow-Credentials", "true");
// 预检请求缓存时间
response.setHeader("Access-Control-Max-Age", "3600");
// 预检请求直接返回
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return false;
}
return true;
}
private boolean isValidOrigin(String origin) {
// 配置允许的源列表
List<String> allowedOrigins = Arrays.asList(
"http://localhost:3000",
"http://localhost:4000",
"http://example.com"
);
return allowedOrigins.contains(origin);
}
}
注册拦截器
Java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private CorsInterceptor corsInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(corsInterceptor)
.addPathPatterns("/**")
.order(1); // 设置最高优先级
}
}
进阶配置:基于配置文件
application.yml
YAML
cors:
allowed-origins:
- http://localhost:3000
- http://localhost:4000
allowed-methods:
- GET
- POST
- PUT
- DELETE
allowed-headers:
- Content-Type
- Authorization
allow-credentials: true
max-age: 3600
配置属性类
Java
@ConfigurationProperties(prefix = "cors")
@Component
public class CorsProperties {
private List<String> allowedOrigins = new ArrayList<>();
private List<String> allowedMethods = new ArrayList<>();
private List<String> allowedHeaders = new ArrayList<>();
private boolean allowCredentials = true;
private long maxAge = 3600;
// getter and setter
}
改进的拦截器
Java
@Component
public class CorsInterceptor implements HandlerInterceptor {
@Autowired
private CorsProperties corsProperties;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
String origin = request.getHeader("Origin");
// 动态配置
if (corsProperties.getAllowedOrigins().contains(origin)) {
response.setHeader("Access-Control-Allow-Origin", origin);
}
response.setHeader("Access-Control-Allow-Methods",
String.join(", ", corsProperties.getAllowedMethods()));
response.setHeader("Access-Control-Allow-Headers",
String.join(", ", corsProperties.getAllowedHeaders()));
response.setHeader("Access-Control-Allow-Credentials",
String.valueOf(corsProperties.isAllowCredentials()));
response.setHeader("Access-Control-Max-Age",
String.valueOf(corsProperties.getMaxAge()));
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return false;
}
return true;
}
}
拦截器 vs 内置CORS配置
| 对比项 | 拦截器实现 | 内置CORS配置 |
|---|---|---|
| 灵活性 | 高,可添加自定义逻辑 | 中等 |
| 配置方式 | 代码配置 | 注解或配置类 |
| 动态控制 | 支持运行时动态调整 | 静态配置 |
| 维护成本 | 较高 | 较低 |
| 学习成本 | 需理解拦截器机制 | 简单 |
注意事项
拦截器的order值越小,优先级越高,确保CORS拦截器在其他拦截器之前执行。
Java
registry.addInterceptor(corsInterceptor)
.addPathPatterns("/**")
.order(Integer.MIN_VALUE); // 最高优先级
要点总结
- 拦截器实现CORS更加灵活可控
- 预检请求(OPTIONS)需要直接返回
- 可结合配置文件实现动态配置
- 注意设置拦截器优先级最高
- 适合需要复杂跨域策略的场景
📝 发现内容有误?点击此处直接编辑