【跨域】SpringBoot跨域,拦截器中,第一次获取的请求头为NULL,发送两次请求的处理方式
背景:
在做前后端分离时,牵扯到跨域,但是已经设置了跨域
前端设置了允许携带Cookie
axios.defaults.withCredentials = true;
后端也配置了跨域
浏览器端查看发送的请求,请求头中包含Authorization
原因:
实际上发送了两次请求,第一次为OPTIONS
请求,第二次才GET/POST...
请求
- 在
OPTIONS
请求中,不会携带请求头的参数,所以在拦截器上获取请求头为空,自定义的拦截器拦截成功 - 第一次请求不能通过,就不能获取第二次的请求了
GET/POST...
第一次请求不带参数,第二次请求才带参数
解决:
在拦截器中,如果请求为OPTIONS
请求,让 OPTIONS
请求返回一个200状态码,表示可以正常访问,然后就会收到真正的GET/POST
请求
String method = request.getMethod(); //输出 OPTIONS/GET/POST。。。 //如果是 OPTIONS 请求,让 OPTIONS 请求返回一个200状态码 if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return false; }
拦截器完整示例
@Component public class HttpRequestInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //origin:指定可以访问本项目的IP String origin = request.getHeader("Origin"); response.setContentType("application/json;charset=UTF-8"); response.setHeader("Access-Control-Allow-Origin", origin); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "1800"); // 设置 受支持请求标头(自定义 可以访问的请求头 例如:Token) response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization,token,Origin,Content-Type,Accept"); // 指示的请求的响应是否可以暴露于该页面。当true值返回时它可以被暴露 response.setHeader("Access-Control-Allow-Credentials", "true"); //如果是OPTIONS请求,让其响应一个 200状态码,说明可以正常访问 if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return false; } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
配置拦截器
自定义的拦截器必须要配置,才能使用
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private HttpRequestInterceptor httpRequestInterceptor; // 配置拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { //设置跨域得拦截器 ,/** 表示拦截所有请求 registry.addInterceptor(httpRequestInterceptor).addPathPatterns("/**"); } }
本文来自博客园,作者:周星星、同学,转载请注明原文链接:https://www.cnblogs.com/rxx1005/p/12781797.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)