Vue前端请求后端接口出现跨域问题(启用拦截器后)

望月思she何时归 2024-07-19 12:33:02 阅读 83

在文章开头先声明当前的问题,前端调用axios方法后还是会出现的这种跨域问题,并且后端已经允许跨域。

Vue前端执行调用后端接口方法如下:(已使用axios跨域)

<code> // 查询用户+高级查询

list() {

this.$axios.post(this.$httpUrl + "/user/list", {

pageSize: this.pageSize,

pageNum: this.pageNum,

id: this.id,

account: this.account,

nickname: this.nickname,

name: this.name,

phone: this.phone,

email: this.email,

sex: this.sex,

age: this.age

})

.then(res => res.data).then(res => {

console.log(res)

if (res.code == 200) {

this.tableData = res.content.content;

this.pageNum = res.content.pageSize;

this.pageNum = res.content.pageNum;

this.total = res.content.total;

} else {

this.$message.error("获取题库数据失败")

}

})

},

后端配置WebConfig允许跨域:

@Override

public void addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**")

//是否发送Cookie

.allowCredentials(true)

//放⾏哪些原始域

.allowedOriginPatterns("*")

.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})

.allowedHeaders("*")

.exposedHeaders("*");

}

在开启拦截器后,拦截器放行路径不会受影响,可以正常进行调用接口,被拦截的路径则会弹出第一张图片一致的跨域错误。以下是整个WebConfig配置,没有问题

@Configuration

public class WebConfig implements WebMvcConfigurer {

@Autowired

private LoginCheckInterceptor loginCheckInterceptor;

@Autowired

private PermissionInterceptor permissionInterceptor;

@Override

public void addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**")

//是否发送Cookie

.allowCredentials(true)

//放⾏哪些原始域

.allowedOriginPatterns("*")

.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})

.allowedHeaders("*")

.exposedHeaders("*");

}

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(loginCheckInterceptor)

.excludePathPatterns("/api/code","/api/employee/login","/api/employee/logout")

.addPathPatterns("/**");

registry.addInterceptor(permissionInterceptor)

.excludePathPatterns("/api/code","/api/employee/login","/api/employee/logout")

.addPathPatterns("/**");

}

}

在开启DeBUG后发现,拦截请求后获取的token值为空

 按照逻辑来说不应该获取不到token,前端页面显示已经sessionStorage存储token

此时回到网络请求中看看刚才发出的接口请求,发现有两个list接口请求

点开请求查看详细信息,发现第一个list请求已经含有token,第二个请求头没有包含token,但发现他的请求方式为OPTIONS

        在搜寻资料后发现,OPTIONS请求是一个预检请求,并不携带请求头数据,不能携带token值,所以验证不通过,抛出了一个异常。前端直接返回跨域问题,这种情况很容易跑偏,我的理解是前端发出的是一个OPTIONS请求,后端跨域放行只放行"GET", "POST", "PUT", "DELETE"方法,所以直接报错。

        解决办法有很多,目标只有一个,放行OPTIONS请求即可。我的解决办法是在拦截器中添加放行操作,将放行判断添加在拦截器开始位置。下面只是其中的一个登录校验拦截器,还有一个权限拦截器,方法同理。

<code>@Slf4j

@Component

public class LoginCheckInterceptor implements HandlerInterceptor {

// 目标资源方法运行前运行,返回ture:放行 反之

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

// 1、获取请求路径url

String url = request.getRequestURL().toString();

log.info("请求的URL:{}", url);

// 2、判断url中是否存在login,如果包含,即为登录操纵,放行

if (url.contains("login")){

log.info("登录操作,放行!");

return true;

}

//放行OPTIONS请求

String method = request.getMethod();

if ("OPTIONS".equals(method)) {

return true;

}

// 3、获取请求头中的令牌

String jwt = request.getHeader("Token");

// 4、判断请求头中的令牌是否为空

if (!StringUtils.hasLength(jwt)){

log.info("请求头为空,返回登录页面!");

Result error = Result.fail("NOT_LOGIN");

// 需要将error转化为json数据格式阿里的fastJSON

String notLogin = JSONObject.toJSONString(error);

response.getWriter().write(notLogin);

return false;

}

// 5、解析token如果解析失败,返回错误结果(未登录)

try {

JwtUtils.parseJWT(jwt);

} catch (Exception e) {

// jwt解析失败

log.info("jwt令牌解析失败,返回登陆信息错误!");

Result error = Result.fail("NOT_LOGIN");

// 需要将error转化为json数据格式阿里的fastJSON

String notLogin = JSONObject.toJSONString(error);

response.getWriter().write(notLogin);

return false;

}

// 6、放行

log.info("令牌合法,放行");

return true;

}

}

关键就是这个

 

重启测试:

第一个list照样为OPTIONS请求,不过这次已经放行处理,第二个list也获取到后端接口返回值,测试成功。有其他问题可以留言进行解决。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。