在使用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
重新运行程序,发送请求,定睛一看控制台,
( ̄_, ̄ )妙啊~
今天又玄学解决了一个问题,心情舒畅。