SpringBoot 2.0 @CrossOrigin 无法跨域问题

在SpringBoot2.0(springframework5.0.2后)中,使用@CrossOrigin注解配置跨域时,需注意allowCredentials默认为false,导致带cookie的跨域请求失败。本文详细解析问题原因,并提供解决方案,通过设置allowCredentials为true来成功实现跨域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前使用SpringBoot 1.5.x,配置跨域一般是直接在controller或是在某一个方法上添加 @CrossOrigin 注解即可,如下代码

/**
 * @author chenws
 * @decription
 * @date 2018/10/18
 */
@RestController
@RequestMapping(value = "xxx")
@CrossOrigin(maxAge = 3600)
public class BuildShapeController {
 
        @CrossOrigin(maxAge = 3600)
	@ApiOperation("xxx")
	@RequestMapping(value = "/xxx",method = RequestMethod.POST)
	public ResponseVO<List<xxx>> listShape(@RequestBody xxx xxx){}
}

没有任何问题,使用的非常好,但是在spring boot 2.0中(springframework5.0.2后),以上方法行不通,这样设置无效。在网上找了n篇文章,都是按照SpringBoot 1.x的方法介绍的,始终无法解决,知道发现碩果兄的这篇文章,问题才得以解决,再次表示万分感谢。文章地址:SpringBoot 2.0 @CrossOrigin 无法跨域问题

查看@CrossOrigin源码

springframework4.3.12:


   /**
	 * Whether the browser should include any cookies associated with the
	 * domain of the request being annotated.
	 * <p>Set to {@code "false"} if such cookies should not included.
	 * An empty string ({@code ""}) means <em>undefined</em>.
	 * {@code "true"} means that the pre-flight response will include the header
	 * {@code Access-Control-Allow-Credentials=true}.
	 * <p>If undefined, credentials are allowed.
	 */
	String allowCredentials() default "";

springframework5.0.2

   /**
	 * Whether the browser should send credentials, such as cookies along with
	 * cross domain requests, to the annotated endpoint. The configured value is
	 * set on the {@code Access-Control-Allow-Credentials} response header of
	 * preflight requests.
	 * <p><strong>NOTE:</strong> Be aware that this option establishes a high
	 * level of trust with the configured domains and also increases the surface
	 * attack of the web application by exposing sensitive user-specific
	 * information such as cookies and CSRF tokens.
	 * <p>By default this is not set in which case the
	 * {@code Access-Control-Allow-Credentials} header is also not set and
	 * credentials are therefore not allowed.
	 */
	String allowCredentials() default "";

By default this is not set in which case the {@code Access-Control-Allow-Credentials} header is also not set and credentials are therefore not allowed.

5.0.2后,allowCredentials默认为false了,再看 DefaultCorsProcessor

if (Boolean.TRUE.equals(config.getAllowCredentials())) {
 
	responseHeaders.setAccessControlAllowCredentials(true);
 
}

allowCredentialstrue时,返回的响应头AccessControlAllowCredentials属性才设置为true

因此凡是客户端带上cookie的请求,都不能实现跨域。

 

解决办法:

在注解中设置allowCredentialstrue即可。

@CrossOrigin(allowCredentials="true",maxAge = 3600)

至此,问题完美解决

<think>好的,我现在需要解决用户在使用@CrossOrigin注解后无法调用getMD5String方法的问题。首先,我得理清楚问题可能的原因。 用户提到在配置了后,某个具体的方法失效了。这说明配置可能影响到了该方法。首先,我应该检查@CrossOrigin的用法是否正确。这个注解可以用在类或方法上,如果类上已经配置了,方法上的配置可能会有冲突。比如,如果类上的注解覆盖了某些设置,可能导致方法级别的配置失效。 然后,考虑配置是否影响到了其他拦截器或过滤器。例如,Shiro或Spring Security的权限验证可能会因为配置而拦截请求。用户之前提到过Shiro的问题,比如没有认证导致错误,所以需要检查是否有权限相关的拦截器阻止了方法的调用。可能需要在Shiro的配置中放行相关路径,或者在Spring Security中配置设置,而不是仅仅依赖@CrossOrigin。 另外,浏览器的CORS预检请求(OPTIONS)是否被正确处理?如果后端没有处理OPTIONS请求,可能导致真正的请求(如POST或GET)无法到达方法。需要确认服务器是否对OPTIONS请求返回了正确的响应头,允许访问。 还有可能是方法本身的路径或请求方式不匹配。比如,@CrossOrigin配置的origins、methods或allowedHeaders与实际请求不符,导致预检失败,从而无法调用方法。需要检查注解中的属性是否与前端请求一致。 另外,日志信息也很重要。用户提到整合了Log4J,可能需要查看日志输出,确认是否有异常或错误信息,比如权限拒绝或方法找不到。如果getMD5String方法需要特定的参数或请求体,可能因为配置导致参数解析失败,比如多RequestBody的问题,参考用户提到的引用[1],可能需要自定义参数解析器。 最后,可能需要全局配置,而不是使用注解。比如,通过WebMvcConfigurer来配置全局设置,避免注解被其他配置覆盖。同时,确保Spring Boot的版本兼容,某些版本可能存在处理的bug,需要升级或调整配置。 总结可能的原因:注解配置冲突、权限拦截器拦截、预检请求处理不当、参数不匹配、参数解析问题等。解决方案应逐步排查这些可能性,调整配置,查看日志,确保所有环节都允许访问。</think>### 问题分析:使用@CrossOrigin注解后无法调用getMD5String方法 #### 1. **检查@CrossOrigin注解配置** - **作用范围**:确认注解是否直接标注在`getMD5String`方法或所在控制器类上。例如: ```java @RestController @CrossOrigin(origins = "*", allowedHeaders = "*") // 类级别配置 public class YourController { @GetMapping("/md5") @CrossOrigin // 方法级别配置(若需要覆盖类级别配置) public String getMD5String() { // ... } } ``` - **属性匹配**:检查`origins`、`methods`、`allowedHeaders`是否与前端请求匹配。例如前端使用`POST`但注解仅允许`GET`会导致失败。 #### 2. **权限框架拦截(如Shiro)** - **路径放行**:若使用Shiro,可能拦截了请求。在Shiro配置中放行`/md5`路径: ```java @Bean public ShiroFilterChainDefinition shiroFilter() { DefaultShiroFilterChainDefinition chain = new DefaultShiroFilterChainDefinition(); chain.addPathDefinition("/md5", "anon"); // 匿名访问 return chain; } ``` - **认证状态检查**:确保请求中携带了必要的Token或Session信息(参考引用[^2]中提到的Shiro认证问题)。 #### 3. **预检请求(OPTIONS)处理** - **自动处理**:Spring Boot默认会处理OPTIONS请求,但若自定义了拦截器(如登录拦截器),需手动放行OPTIONS请求: ```java public class YourInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpStatus.OK.value()); return false; } return true; } } ``` #### 4. **全局配置覆盖** - **替代注解方案**:使用`WebMvcConfigurer`全局配置,避免注解冲突: ```java @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .allowedHeaders("*"); } } ``` #### 5. **参数解析问题** - **多RequestBody冲突**:若`getMD5String`方法需要多个`@RequestBody`参数,需实现自定义解析器(参考引用[^1]): ```java public class MultiRequestBodyResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(RequestBody.class); } @Override public Object resolveArgument(/* 参数解析逻辑 */) { // 自定义解析逻辑 } } ``` #### 6. **日志排查** - **启用详细日志**:通过Log4J输出详细调试信息(参考引用[^3]): ```xml <!-- log4j2.xml --> <Configuration> <Loggers> <Logger name="org.springframework.web" level="debug"/> </Loggers> </Configuration> ``` - **检查异常堆栈**:查看是否有`Access-Control-Allow-Origin`缺失、`405 Method Not Allowed`或权限拒绝日志。 --- ### 最终解决方案步骤 1. **优先使用全局配置**,禁用`@CrossOrigin`注解测试是否恢复。 2. **检查Shiro/Security放行规则**,确保路径未被拦截。 3. **捕获请求日志**,确认请求头、方法类型与后端配置一致。 4. **升级Spring Boot版本**(若版本低于2.4.x,存在相关兼容性问题)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值