做项目的时候,有个新来的同事让我帮忙看个问题。项目本地代码运行正常,但是请求报401(也可能报404),
打开控制台一看,没有拿到token,以为是前端问题,然后就去看前端获取token的文件,看了半天,调试了半天,可以正常拿到token。。然后就开始考虑是后端问题,果然,打印出来的token显示是null。
原因:
查询资料发现,查询请求发出前的OPTIONS请求是检查服务器是否支持跨域请求的,它并没有带上headers中的token信息,所以后台在接到OPTIONS请求后获取不到token信息,直接返回了。所以前端也出现跨域情况。
分析:
· 实际上发送了两次请求,第一次为OPTIONS请求,第二次才GET/POST...请求;
· 在OPTIONS请求中,不会携带请求头的参数,所以在拦截器上获取请求头为空,自定义的拦截器拦截成功;
· 第一次请求不能通过,就不能获取第二次的请求了GET/POST...
· 第一次请求不带参数,第二次请求才带参数;
解决:
只需要放行OPTIONS请求即可。
在拦截器中,如果请求为OPTIONS
请求,则返回true,表示可以正常访问,然后就会收到真正的GET/POST
请求
//放行登录请求
if (request.getRequestURI().contains("/user/login")) {
return true;
}
//放行OPTIONS请求
String method = request.getMethod();
if ("OPTIONS".equals(method)) {
return true;
}
//取出请求头中的token
String token = request.getHeader("token");
System.out.println("token: " + token);
if (StringUtils.isEmpty(token)) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return false;
}
参考:前后端分离,SpringBoot拦截器中,获取的请求头token为NULL问题解决 - Arbitrary233 - 博客园