在使用Vue和SpringBoot进行前后端分离开发时,涉及到请求跨域的问题。

看了一些教程后在后端编写了WebMvc的配置类:

@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
    /**
     * 配置跨域,允许localhost:8080访问
    */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedHeaders("*")
                .allowedMethods("*")				
                .maxAge(1800)
                .allowedOrigins("http://localhost:8080");
    }
}

前端则使用axios进行网络请求。这里封装了一个post请求。

import axios from 'axios'

const baseURL = 'http://localhost:8081'

export function postData(url, config) {
  const instance = axios.create({
    baseURL,
    timeout: 5000 //5秒
  }) 
  //响应拦截器,只把返回结果中的data返回
  instance.interceptors.response.use(
    res => {
      return res.data
    }, 
    err => {
      console.log(err)
  })
  return  instance.post(url,config)
}

这样子便可以进行跨域请求了。

但是,当后端响应一个get请求,往session中保存了一些数据;然后前端再往后端发送一个post请求,请求处理时想要取出刚才保存在session中的数据时却取出了null,震惊。

比如在用户登录这个场景中,前端在渲染登录页面时以get方式向后端发送了一个获取验证码的请求。

<img :src="vcUrl" @click="updateVerifyCode" alt="">
vcUrl: 'http://localhost:8081/verifyCode?time='+new Date()

SpringBoot后端的controller中响应这个请求,并把验证码保存在了session中。

    @GetMapping("/verifyCode")
    public void verifyCode(HttpSession session, HttpServletResponse resp) throws IOException {
        //生成验证码和验证码图片
        VerificationCode code = new VerificationCode();
        BufferedImage image = code.getImage();
        String text = code.getText();
        //将验证码存入session
        session.setAttribute("verify_code", text);
        //System.out.println(session.getAttribute("verify_code"));
        VerificationCode.output(image,resp.getOutputStream());
        System.out.println("[验证码]:"+text);
    }

然后用户便填写登录表单,提交到后端;首先进行校验的便是验证码,便理所应当地取出刚才存进session的验证码进行比对。

postData('/login', this.loginForm).then(resp => {
	//省略成功回调
})
	@PostMapping("/login")
    public SysResult loginHandler(@RequestBody JSONObject object, HttpSession session) {
        //取出参数
        String email = object.getString("email");
        String password = object.getString("password");
        String code = object.getString("code");
        //验证验证码
        if(code != session.getAttribute("verify_code")){
            return SysResult.error("验证码错误");
        }
        User user = userService.login(email, password);
        //验证用户信息
        if(user == null){
           return SysResult.error("用户或密码错误");
        }
		//省略。。。
        return SysResult.ok("登录成功", userDto);
    }

然后session中的值取出是null !!

极度疑惑,便又写了一个controller,这次是用get方式,

    @GetMapping("/hello")
    public SysResult hello(HttpSession session){
        String verify_code = (String) session.getAttribute("verify_code");
        return SysResult.ok("ok",verify_code);
    }

居然取到了!!!为何会出现这种情况呢?百思不得其解。

于是在网上疯狂冲浪,然而也没有得到答案,在浏览那些个网页时,虽是没有遇到和我一般问题的人,不过我却发现神通广大的网友们在解决其他一些跨域问题的时候,不仅会在SpringBoot中配置跨域,axios也会配置。

于是乎,我本着玄学解决bug的原则,配置了一下axios的全局配置。说来也不多,就一句:

axios.defaults.withCredentials = true

重新运行程序,发送请求,定睛一看控制台,

妙啊
( ̄_, ̄ )妙啊~

今天又玄学解决了一个问题,心情舒畅。

更多推荐