1、前后端不分离情况
在处理session过程中,如果前后端项目在一个容器中,session是可以被获取的。例如如下项目结构:
结构

后端的代码是基本的设置值、获取值、销毁值的内容:

运行结果



由此可见,在前后统一的项目中,session通道不会直接断掉,除非是在关闭浏览器或者session超时后才会变化。
2、前后端分离情况
结构

将对应的session_demo.html放到了前端的项目当中
运行结果(因安全策略,跨域错误)

这里对三个跨域请求的后台设置允许跨域的请求头即可。

跨域运行后获取的Session不一致


也会导致其他按钮使用服务时产生新的通道:


3、原因与解决思路
问题原因
Session的工作原理:当用户首次访问服务器时,服务器会创建一个session,并生成一个唯一的session ID。这个ID通常存储在cookie中,并随请求一起发送回客户端。后续的请求中,客户端将携带这个session ID,服务器通过这个ID来识别用户的会话,并保持状态。
1、Session 是一种服务器端的存储方式,用于存储用户的状态信息。它允许服务器在多个页面请求或访问周期中保持状态。在 HTTP 协议中,默认是无状态的,意味着每次请求都是独立的,服务器不保留任何关于客户端的信息。Session 机制通过在服务端维护状态信息,使得服务器能够在多次请求之间识别同一个客户端,当 Session 超时或被显式销毁时,服务器会停止跟踪用户的状态。如果用户关闭浏览器,客户端的 Cookie 可能会丢失,但服务器端的 Session 数据可能仍然存在,直到超时或被服务器清理。
2、在前后端分离的架构中,前端发起请求和服务端响应确实涉及到多个独立的HTTP请求,因为每次HTTP请求都是无状态的。因此该demo中也是出现了每次访问sessionId不一致的情况。
可以配置为将session ID存储在cookie中,并随每个请求发送。这样,即使请求是独立的,服务器也能够通过session ID来识别和维持用户的会话状态。
解决思路
我们需要通过Cookie来帮助我们解决前后端分离时session不一致的问题。
解决方法
每次使用session时在头部中携带cookie信息,用于保证每次请求和响应都通过cookie携带的sessionId找到对应的Session。
操作步骤
1、我们在前端进行请求的时候添加以下内容,意味传输的时候携带Cookie信息

 $.ajax({
                ...
                //新增 对cookie的携带
                xhrFields: {
                    withCredentials: true
                },
                ...
            })2、后端需要设置对应的跨域ip,以及同意携带cookie的方法

@WebServlet("/setSession")
public class SetSessionServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//       获取session
        HttpSession session = req.getSession();
        String user = req.getParameter("user");
        //新增 限制的访问地址
        String host = "http://localhost:5500";
        resp.setHeader("Access-Control-Allow-Origin",host);
        
        //新增 允许携带cookie
        resp.setHeader("Access-Control-Allow-Credentials","true");
    
        resp.setContentType("text/html;charset=UTF-8");
        if (user == null){
            resp.getWriter().println("session未存放数据!");
        }else {
            //session中设置属性
            session.setAttribute("user",user);
            resp.getWriter().println("session已存放数据,sessionId为:"+req.getSession().getId()); //获取session的唯一id
        }
    }
}
4.优化后运行结果



5、附件
前端项目代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5500 前端</title>
</head>
<body>
    <button id="getSession" onclick="getSession()">获取session</button>
    <button id="setSession" onclick="setSession()">存放session</button>
    <button id="rmSession" onclick="removeSession()">移除session</button>
    <script src="./js/jQuery-3.7.1.js"></script>
    <script>
        function getSession() {
            $.ajax({
                url: 'http://localhost:8081/Java_Web_Servlet_war_exploded/getSession',
                //新增 对cookie的携带
                xhrFields: {
                    withCredentials: true
                },
                method: 'GET',
                success: function (resp) {
                    alert(resp)
                }
            })
        }
        function setSession() {
            $.ajax({
                url: 'http://localhost:8081/Java_Web_Servlet_war_exploded/setSession',
                //新增 对cookie的携带
                xhrFields: {
                    withCredentials: true
                },
                data: { 'user': 'admin' },
                method: 'POST',
                success: function (resp) {
                    alert(resp)
                }
            })
        }
        function removeSession() {
            $.ajax({
                url: 'http://localhost:8081/Java_Web_Servlet_war_exploded/removeSession',
                //新增 对cookie的携带
                xhrFields: {
                    withCredentials: true
                },
                method: 'GET',
                success: function (resp) {
                    alert(resp)
                }
            })
        }
    </script>
</body>
</html>后端项目结构:

后端代码-1:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/getSession")
public class getSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//       获取session
        HttpSession session = req.getSession();
        String user = (String) session.getAttribute("user");
        String host = "http://localhost:5500";
        resp.setHeader("Access-Control-Allow-Origin",host);
        resp.setHeader("Access-Control-Allow-Credentials","true");        resp.setContentType("text/html;charset=UTF-8");
        if (user == null) {
            resp.getWriter().println("你的session没有存放数据!");
        } else {
            resp.getWriter().println("sessionId为"+session.getId()+",存放的数据为:" + user);
        }
    }
}后端代码-2:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/setSession")
public class SetSessionServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//       获取session
        HttpSession session = req.getSession();
        String user = req.getParameter("user");
        String host = "http://localhost:5500";
        resp.setHeader("Access-Control-Allow-Origin",host);
        resp.setHeader("Access-Control-Allow-Credentials","true");
        resp.setContentType("text/html;charset=UTF-8");
        if (user == null){
            resp.getWriter().println("session未存放数据!");
        }else {
            //session中设置属性
            session.setAttribute("user",user);
            resp.getWriter().println("session已存放数据,sessionId为:"+req.getSession().getId()); //获取session的唯一id
        }
    }
}后端代码-3:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/removeSession")
public class RemoveServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = (String)req.getSession().getAttribute("user");
        req.getSession().removeAttribute("user");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/hml;charset=UTF-8");
        String host = "http://localhost:5500";
        resp.setHeader("Access-Control-Allow-Origin",host);
        resp.setHeader("Access-Control-Allow-Credentials","true");
        resp.getWriter().println("你的sessionId是:"+req.getSession().getId()+",移除了user:"+username);
    }
}


















