1. 前后端分离中session的状态
以前前后端都在一起的时候,没有跨域的问题,session是可以确定的,但是在跨域的时候,我每次访问,都会像是新的一台主机访问我的服务器,就会造成session的新建,所以不能能访问到原来的session数据
![还是我只能用浏览器的sessionStroger](https://img-blog.csdnimg.cn/fb5d5db7648b40339cd9f8e24d936c5f.png#pic_center)
2.解决办法
**2.1 前端
前端跨域访问后端接口, 在浏览器的安全策略下默认是不携带cookie的, 所以每次请求都开启了一次新的会话
所以我们就需要前端发送的数据中可以包含被后端识别
axios.defaults.withCredentials = true;
(设置cross跨域 并设置访问权限 容许跨域携带cookie信息)
注意!!!-》需要所有请求前添加
列如:
//设置cross跨域 并设置访问权限 容许跨域携带cookie信息
axios.defaults.withCredentials = true;
//通过axios向后端发送post请求
axios.post('http://localhost:8002/stujava/getSession',role).then(function (res) {
if(res.data[0] !=null){
that.session_vue.login=res.data[0][0];
sessionStorage.removeItem("userName");
sessionStorage.setItem("userName",that.session_vue.login.userName);
}else{
alert("未登录");
window.location.replace('../../')
}
}).catch(function (error) {
alert(error);
});
2.2 后端
1.前端发送过来的数据已经携带了cookie,那么我们怎样识别出来呢?
2.如同我们上面说的,每发送一次链接,后端都会以为是一台新的主机来访问,所以我们就需要针对每一次请求来进行处理。
这里我们就需要用到拦截器
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("经过了拦截器");
response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));//支持跨域请求
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");//是否支持cookie跨域
response.setHeader("Access-Control-Allow-Headers", "Authorization,Origin, X-Requested-With, Content-Type, Accept,Access-Token");//Origin, X-Requested-With, Content-Type, Accept,Access-Token
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
System.out.println("controller 执行完了");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
System.out.println("我获取到了一个返回的结果:"+response);
System.out.println("请求结束了");
}
- preHandle方法:每次调用链接都会执行一次,里面写我们的逻辑代码
- postHandle方法:Controller层执行完后会执行
- afterCompletion方法:最后执行
我们需要注册到适配器中
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
}
}
实现类在注解扫描包下自行创建
2.3 测试
@RequestMapping("login")
public List login(HttpServletRequest request,@RequestBody Login login){
List list = loginService.LoginByAll(login);
if (list.size()==1){
HttpSession session=request.getSession();
session.setAttribute(login.getRole(), list);
System.out.println("session="+session.getAttribute(login.getRole()));
}
System.out.println(request.getSession().getAttribute(login.getRole()));
return list;
}
@RequestMapping("getSession")
public List getSession(HttpServletRequest request,@RequestBody Login login){
System.out.println(login);
System.out.println(request.getSession().getAttribute(login.getRole()));
List list=new ArrayList<>();
list.add(request.getSession().getAttribute(login.getRole()));
return list;
}
结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/95bc7dcf705d4b89bad6ed6f0294439d.png#pic_center)
3.总结
1.需要在前端代码每次发送请求时添加 axios.defaults.withCredentials = true 这段代码
2.配置拦截器注册到适配器中