全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-18 6 分钟 ✍️ juanwangdev

拦截器实现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)需要直接返回
  • 可结合配置文件实现动态配置
  • 注意设置拦截器优先级最高
  • 适合需要复杂跨域策略的场景

📝 发现内容有误?点击此处直接编辑

← 上一篇 SpringMVC CORS配置
下一篇 → 跨域问题产生原因
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库