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

文章讲述了前端使用axios发起请求时遇到跨域问题,尤其是在登录拦截器中,OPTIONS请求被拦截导致验证失败。作者通过分析发现,解决方案是放行OPTIONS请求,并在登录校验拦截器中进行处理,确保后端接口的正常访问。
摘要由CSDN通过智能技术生成

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

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

    // 查询用户+高级查询
    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请求即可。我的解决办法是在拦截器中添加放行操作,将放行判断添加在拦截器开始位置。下面只是其中的一个登录校验拦截器,还有一个权限拦截器,方法同理。

@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也获取到后端接口返回值,测试成功。有其他问题可以留言进行解决。

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值