前端访问后台接口时,浏览器报错,跨域无法访问。
报错信息如下:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
经过一番百度之后,需要在控制器上添加处理跨域的注解,
注解添加后,再次访问接口,又有了新的报错:
Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
根据资料显示,这个是因为浏览器预检请求失败,复杂请求会做预检请求,比如header中有自动以的属性等情况,当前的报错是指OPTION 请求失败,需要后端放行 OPTION 请求。
解决方法是定义个拦截器:
CorsInterceptor.java
package com.interceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
@Component
public class CorsInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "86400");
response.setHeader("Access-Control-Allow-Headers", "*");
// 如果是OPTIONS则结束请求
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
response.setStatus(HttpStatus.NO_CONTENT.value());
return false;
}
return true;
}
}
然后将拦截器注册到全局拦截器中,使其生效。
WebConfig.java
package com.config;
import com.interceptor.CorsInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private CorsInterceptor corsInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//跨域拦截器需放在最上面
registry.addInterceptor(corsInterceptor);
}
}
再次访问接口,请求正常返回了
参考链接:
「日常报错」Response to preflight request doesn't pass access control check: It does not have HTTP ok status. - Posase - 博客园 (cnblogs.com)
为什么出现OPTIONS?SpringBoot接口跨域解决方案 - 简书 (jianshu.com)