1. session 丢失
在后端代码中,返回一个字符串,内容为重定向地址。
@ResponseBody
@RequestMapping("autoLogin")
public String doctorAutoLogin(HttpServletRequest request, HttpServletResponse response, HttpSession session,
@RequestParam(value="account", required=true) String account) {
clearSessionAndLogout(request);
String url = request.getRequestURL().toString();
url = url.substring(0, url.indexOf("/login"));
String loginUrl = url + "/portal/index/person";
...
// 处理请求会话,在 session 中存入 user
successLoginHandle(request, response, session, user, loginToken);
...
return loginUrl;
}
前端代码:
class App extends Component {
constructor(props) {
super(props);
this.autoLogin = this.autoLogin.bind(this);
}
render() {
return (
<div>
<a onClick={this.autoLogin}>自动登陆</a>
</div>
);
}
autoLogin() {
axios.post("http://localhost:3000/login/autoLogin").then((res) => {
window.location.href = res.data.data;
}).catch((e) => {
console.log(e);
})
}
}
执行结果事与愿违,页面虽然进行了重定向,但是没有自动登录成功。通过后台代码断点查看,在登陆时获取 session 中的 user 时,返回为 null。
网上文章 session lost with window.location.href 的说法是:window.location.href 之后,重新创建了一个新的 httpcontext ,所以导致 session 丢失了。
问题的解决方式:
-
把 session 数据带到你重定向的页面去(未验证)。Session lost window.location.href
window.onbeforeunload = function() { localStorage.setItem( "session", JSON.stringify( window.sessvars) ); }; window.onload = function() { window.sessvars = JSON.parse( localStorage.getItem( "session") || "{}" );; };
-
把重定向操作放到后台去做,这样页面就不会创建新的 httpContext,session 数据就能获取到了
@RequestMapping("autoLogin") public String doctorAutoLogin(HttpServletRequest request, HttpServletResponse response, HttpSession session, @RequestParam(value="account", required=true) String account) { clearSessionAndLogout(request); String url = request.getRequestURL().toString(); url = url.substring(0, url.indexOf("/login")); String loginUrl = "redirect:" + url + "/portal/index/person"; ... // 处理请求会话,在 session 中存入 user successLoginHandle(request, response, session, user, loginToken); ... return loginUrl; }
去掉
@ResponseBody
标注,如果有这个标注,返回值将作为响应体的内容返回。在 loginUrl 前面拼接redirect:
字符串。