解决关于HTML+JS + Servlet 实现前后端请求Session不一致的问题

news2024/11/26 20:26:04

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);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2219616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sign Language Dataset: 聋哑人手语数据集(猫脸码客 第209期)

Sign Language Dataset: 聋哑人手语数据集 摘要&#xff1a;手语是聋哑人群体进行沟通交流的重要工具&#xff0c;通过手势、动作及面部表情的组合表达复杂的思想和情感。随着计算机视觉和人工智能技术的发展&#xff0c;聋哑人手语数据集在促进手语识别、翻译和交互系统开发中…

计算机指令系统,打个结~

计算机指令系统是计算机硬件与软件之间的桥梁&#xff0c;它定义了计算机能够执行的各种操作。一个完善的指令系统不仅影响着计算机的性能&#xff0c;还直接决定了计算机能够完成的任务种类和复杂度。本文将从计算机指令的基本概念出发&#xff0c;探讨指令系统的分类、常见指…

第13篇:无线与移动网络安全

目录 引言 13.1 无线网络的安全威胁 13.2 无线局域网的安全协议 13.3 移动通信中的安全机制 13.4 蓝牙和其他无线技术的安全问题 13.5 无线网络安全的最佳实践 13.6 总结 第13篇&#xff1a;无线与移动网络安全 引言 无线和移动网络的发展为我们的生活带来了极大的便利…

cisco网络安全技术第3章测试及考试

测试 使用本地数据库保护设备访问&#xff08;通过使用 AAA 中央服务器来解决&#xff09;有什么缺点&#xff1f; 试题 1选择一项&#xff1a; 必须在每个设备上本地配置用户帐户&#xff0c;是一种不可扩展的身份验证解决方案。 请参见图示。AAA 状态消息的哪一部分可帮助…

Java程序设计:spring boot(2)

目录 1 Spring MVC 零配置创建与部署 1.1 创建Spring MVC Web⼯程 1.2 pom.xml 添加坐标相关配置 1.3 添加源代码 1.4 添加视图 1.5 SpringMVC 配置类添加 1.6 入口文件代码添加 1.7 部署与测试 2 Spring Boot 概念&特点 2.1 框架概念 2.2 框架特点 2.3 Spring…

微知-如何临时设置服务器风扇转速?(ipmitool raw 0x30 0x30 0x02 0xff 0x40)

服务器风扇可以通过PWM输出来控制转速。 设置方式 设置单次PWM ipmitool raw 0x30 0x30 0x02 0xff 0x40如果要持续设置需要类似while循环持续输出&#xff1a; while true; do ipmitool raw 0x30 0x30 0x02 0xff 0x64; done > /dev/null参数说明&#xff1a; 其他参数&a…

Qt(简介)

1. Qt简介 Qt是一个基于C的图形用户界面&#xff08;GUI&#xff09;框架&#xff0c;可以开发可视化人机交互程序&#xff0c;但是这并不是Qt的全部。Qt除了可以绘制漂亮的界面外&#xff0c;还包含很多其他的功能&#xff1a;多线程、数据库、图像处理、音视频处理、网络通信…

CentOS安装NVIDIA驱动、CUDA以及nvidia-container-toolkit

0.提前准备 0.1.更新yum源&#xff08;以阿里为例&#xff09; 0.1.1 备份当前的yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 0.1.2 下载新的CentOS-Base.repo 到/etc/yum.repos.d/ CentOS 5 wget -O /etc/yum.repos.d/CentOS-Base…

【LeetCode每日一题】——523.连续的子数组和

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 前缀和 二【题目难度】 中等 三【题目编号】 523.连续的子数组和 四【题目描述】 给你一个…

github学生认证(白嫖copilot)-Why are you not on campus?不在校园内

详细申请操作流程可参考如下博文&#xff1a;从0开始的github学生认证并使用copilot教程&#xff08;超详细&#xff01;&#xff09;_copilot学生认证-CSDN博客 在此记录解决“Why are you not on campus?”提示的方法&#xff1a; 当出现这个提示时&#xff0c;说明在选择学…

2024年底蓝奏云最新可用API接口列表 支持优享版 无需手动抓取cookie

Lanzou Pro V1 接口列表 API状态版本路由获取文件与目录✅^1.0.1/v1/getFilesAndDirectories?url{}&page{}获取目录✅^1.0.0/v1/getDirectory?url{}获取文件✅^1.0.1/v1/getFiles?url{}&page{}搜索文件✅^1.0.0/v1/searchFile?url{}&wd{}依Id解析✅^1.0.2/v1/…

从0-1实战演练后台管理系统 (2)从零开始:Pure Admin 环境搭建完全指南,小白也能轻松掌握!

在开始使用Pure Admin之前&#xff0c;我们需要先了解一下Pure Admin是什么? vue-pure-admin (opens new window)是一款开源完全免费且开箱即用的中后台管理系统模版。完全采用 ECMAScript 模块&#xff08;ESM&#xff09;规范来编写和组织代码&#xff0c;使用了最新的 Vue3…

【原创】java+ssm+mysql计算机等级考试网系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

【ESP32-IDFV5.3.1开发】带SSL的MQTT-demo连接教程

目录 1.VSCODE以及IDF环境配置(略) 2.准备demo 2.1打开VSCODE&#xff0c;主菜单创建示例 找到SSL对应demo&#xff0c;点击创建&#xff0c;并成功创建项目&#xff0c;点击编译&#xff0c;显示编译成功即可以下一步。 确认该demo支持的开发板是你手上的开发板 3.修改demo配…

论文略读:Graph Neural Processes for Spatio-Temporal Extrapolation

2023 KDD 1 背景 时空图数据&#xff0c;无论是交通数据&#xff0c;还是空气质量数据&#xff0c;气候数据。在理想情况下&#xff0c;这些数据应该是细粒度的。 但由于高昂的成本&#xff0c;在某一地区部署和维护足够多的传感器往往是不现实的 ——>因此&#xff0c;许…

Android Studio 的 Gradle 任务列表只显示测试任务

问题现象如下&#xff1a; 问题原因&#xff1a; 这是因为Android Studio 设置中勾选了屏蔽其他gradle任务的选项。 解决方法&#xff1a; File -> Settings -> Experimental 取消勾选Only include test tasks in the Gradle task list generated during Gradle Sync&…

【纯前端excel导出】vue2纯前端导出excel,使用xlsx插件,修改样式、合并单元格

官网&#xff1a; 1、xlsx-js-style xlsx-js-style | xlsx-js-style homepage 2、xlsx SheetJS 中文网 一、使用第三方插件 1、安装 npm install xlsx-js-style 2、引入 import xlsx from xlsx-js-style xlsx插件是基础的导出&#xff0c;不可以修改样式&#xff0c;直接xlsx-s…

Netty通信过程中编解码技术

Netty通信过程中编解码技术 粘包/拆包问题为什么有拆包/粘包MTU最大传输单元和MSS最大分段大小滑动窗口TCP报文如何确保数据包按次序到达且不丢数据Nagle算法 拆包/粘包解决方案 Netty实现自定义通信协议通信协议设计Netty如何实现自定义通信协议 粘包/拆包问题 如何获取一个完…

Discuz | 全站多国语言翻译和繁体本地转换插件 特色与介绍

Discuz全站多国语言翻译和繁体本地转换插件 特色与介绍 特殊&#xff1a;集成了2个开源库1.多国语言翻译 来自&#xff1a;github.com/xnx3/translate特色&#xff1a;无限使用接口 免费使用2个翻译端 带有一级和二级缓存 实现秒翻译 2.简体 繁体&#xff08;台湾&#xff09…

全新子比主题7.9.2开心版 子比主题最新版源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 wordpress zibll子比主题7.9.2开心版 修复评论弹授权 可做付费下载站 含wordpress搭建视频教程zibll子比主题安装视频教程支付配置视频教程&#xff0c;视频都是语音讲解&#xff0c;…