关于springboot跨域与拦截器的问题
今天写代码的时候遇到的一个问题,在添加自己设置的token拦截器之后,报错:
“ERROR
Network Error
AxiosError: Network Error
at XMLHttpRequest.handleError (webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:112:14)
at Axios.request (webpack-internal:///./node_modules/axios/lib/core/Axios.js:54:41)
”
先说解决办法,然后进行分析:
在token拦截器中加入判断句,如果这是个预检请求则直接放行
if (request.getMethod().equalsIgnoreCase("OPTIONS")) {
return true;
}
详细分析过程:
代码中设置的跨域文件:
package com.frontend.pusharticle.comment;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
//是否发送Cookie
.allowCredentials(true)
//放⾏哪些原始域
.allowedOriginPatterns("*")
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE", "OPTIONS"})
.allowedHeaders("*")
.exposedHeaders("*")
.maxAge(3600); // 预检请求的缓存时间(秒);
}
}
设置的token拦截器
package com.frontend.pusharticle.comment;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import java.util.Enumeration;
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从请求头中获取token
Enumeration<String> headerNames = request.getHeaderNames();
// 打印所有请求头信息
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
System.out.println(headerName + ": " + headerValue);
}
if (request.getMethod().equalsIgnoreCase("OPTIONS")) {
return true;
}
String token = request.getHeader("Authorization");
// 检查token是否存在且格式正确
System.out.println(token);
if (token == null || !token.startsWith("Bearer ")) {
// 如果没有token或格式不正确,返回401 Unauthorized状态码
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Unauthorized: No valid token provided");
return false; // 终止请求处理链
}
System.out.println(token.substring(7));
if (!Token.validateToken(token.substring(7))) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Unauthorized: Invalid token");
return false;
}
return true; // 允许请求继续
}
}
但是获取到的token = request.getHeader(“Authorization”);一直是空的,查询了一下谷歌开发者模式中的请求头,发现明明Authorization是存在的
就很蒙圈,于是用了postman尝试,发现postman是可以用的,然后将所有的请求头元素打印了,发现里面确实没有Authorization,但是却有access-control-request-headers: authorization,content-type,终于问题得到解决,这是一个预检请求,而不是真正的请求,所以直接在token拦截器加一个判断就可以
if (request.getMethod().equalsIgnoreCase("OPTIONS")) {
return true;
}
判断是否为预检命令行,如果是直接放行