Java注解篇:@CrossOrigin

前言

        在现代前后端分离的开发模式中,跨域请求(CORS)成为了不可避免的问题。浏览器的同源策略限制了不同源之间的请求交互,而 Spring Framework 为了解决这一问题,引入了 @CrossOrigin 注解。

    @CrossOrigin 是 Spring 4.2 引入的注解,允许我们在控制器或具体方法上启用跨域请求支持。它是实现 CORS 的便捷方式。

        本文将详细介绍 @CrossOrigin 的使用方法、注解参数、实际场景中的应用示例,以及其底层实现原理,帮助你全面理解并灵活使用该注解。


一、跨域基础知识

1. 什么是跨域

        跨域是指浏览器不能执行其他域下的脚本。一个域名下的网页去请求另一个域名下的资源,就构成了跨域。常见的跨域情况包括:

  • 协议不同(http vs https)

  • 域名不同(example.com vs api.example.com)

  • 端口不同(example.com:8080 vs example.com:8081)

2. 浏览器的同源策略

        同源策略(Same-Origin Policy)是浏览器的一个安全功能,它阻止一个源的 JavaScript 脚本去访问另一个源的内容。

3. CORS(跨源资源共享)

        CORS 是一种机制,它通过设置响应头来告诉浏览器:当前资源允许哪些域名访问,从而实现跨源访问。

常见的响应头包括:

  • Access-Control-Allow-Origin

  • Access-Control-Allow-Methods

  • Access-Control-Allow-Headers

  • Access-Control-Allow-Credentials


二、@CrossOrigin 注解使用

1. 基本使用

在控制器类上添加 @CrossOrigin

@CrossOrigin
@RestController
@RequestMapping("/api")
public class MyController {
    @GetMapping("/data")
    public String getData() {
        return "跨域数据";
    }
}

这将允许所有源对 /api/data 进行访问。

2. 作用范围

  • 类级别:对控制器中所有方法生效。

  • 方法级别:只对该方法生效,优先级高于类级别注解。

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://example.com")
    @GetMapping("/open")
    public String openAccess() {
        return "example.com 可访问";
    }

    @GetMapping("/restricted")
    public String restrictedAccess() {
        return "无跨域支持";
    }
}

3. 常用参数

属性描述
origins允许哪些来源访问,默认允许所有(*)
methods允许的 HTTP 方法(如 GET、POST)
allowedHeaders允许的请求头
exposedHeaders响应中暴露的头信息
allowCredentials是否允许携带 Cookie(默认为 false)
maxAge预检请求的缓存时间(单位:秒)
示例
@CrossOrigin(
    origins = "http://localhost:3000",
    methods = {RequestMethod.GET, RequestMethod.POST},
    allowedHeaders = {"Content-Type", "Authorization"},
    allowCredentials = "true",
    maxAge = 3600
)
@GetMapping("/secure-data")
public String secureData() {
    return "安全数据";
}

三、全局跨域配置

除了使用 @CrossOrigin 注解,我们也可以通过配置类来设置全局跨域策略:

@Configuration
public class CorsGlobalConfiguration implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:3000")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

全局配置可以替代注解形式,适用于统一配置策略的项目。


四、实现原理分析

1. 注解处理入口

    @CrossOrigin 是通过 Spring MVC 的处理器拦截器和过滤器链处理的,其底层依赖 CorsProcessor

        在 DispatcherServlet 初始化过程中,会将 HandlerMappingHandlerAdapter 组合成执行链,而跨域处理通过注册 CorsInterceptor 实现。

2. 核心组件

CorsFilter

    CorsFilter 是 Spring Web 提供的过滤器,用于处理所有请求的 CORS 校验。

public class CorsFilter extends OncePerRequestFilter {
    private final CorsConfigurationSource configSource;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
        CorsConfiguration corsConfig = this.configSource.getCorsConfiguration(request);
        CorsProcessor processor = new DefaultCorsProcessor();
        processor.processRequest(corsConfig, request, response);
    }
}
DefaultCorsProcessor

        该类负责核心的跨域逻辑,包括解析请求头、设置响应头等。

public boolean processRequest(@Nullable CorsConfiguration config, HttpServletRequest request, HttpServletResponse response) {
    if (!this.isCorsRequest(request)) {
        return true;
    }
    // 校验 Origin、方法、头部等
    // 设置 Access-Control-* 响应头
    return true;
}

3. 与注解的结合

        当控制器或方法上有 @CrossOrigin 注解时,Spring 会自动解析注解配置并生成 CorsConfiguration 对象,注入到请求的上下文中,最终由 CorsFilter 应用。


五、注意事项

  1. allowCredentials = true 时,allowedOrigins 不能为 *,否则浏览器会拦截。

  2. 浏览器对 OPTIONS 请求是自动发出的“预检请求”,务必允许该方法。

  3. 不同浏览器对 CORS 处理略有差异,需进行充分测试。

  4. 建议跨域配置集中管理,避免分散在多个注解中。


六、常见问题与排查

问题 1:浏览器提示 CORS 错误

  • 检查响应中是否包含 Access-Control-Allow-Origin

  • 确认服务器是否允许对应的方法与头信息

  • 检查是否为预检请求被拒绝

问题 2:Cookie 无法携带

  • 需设置 allowCredentials = true

  • 客户端必须设置 xhr.withCredentials = true

  • 不能使用 * 通配源


七、总结

    @CrossOrigin 是一个简单但非常实用的注解,极大简化了跨域配置,特别适合前后端分离架构下的 API 接口服务。

        通过结合全局配置和方法级注解,我们可以灵活控制不同接口的访问策略,从而兼顾安全性与开发便利。掌握 @CrossOrigin 的使用和底层原理,是现代 Spring Boot 开发者的基本功之一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Stay Passion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值