当前位置: 首页 > news >正文

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

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 {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//       获取sessionHttpSession session = req.getSession();String user = req.getParameter("user");//新增 限制的访问地址String host = "http://localhost:5500";resp.setHeader("Access-Control-Allow-Origin",host);//新增 允许携带cookieresp.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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//       获取sessionHttpSession 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 {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//       获取sessionHttpSession 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 {@Overrideprotected 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);}
}

相关文章:

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

1、前后端不分离情况 在处理session过程中&#xff0c;如果前后端项目在一个容器中&#xff0c;session是可以被获取的。例如如下项目结构&#xff1a; 结构 后端的代码是基本的设置值、获取值、销毁值的内容&#xff1a; 运行结果 由此可见&#xff0c;在前后统一的项目中&a…...

ECharts饼图-饼图34,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个饼图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供详…...

如何实现安川MP3300运动控制器与西门子1200系列PLC进行ModbusTCP通讯

在工业自动化中&#xff0c;实现不同品牌、不同型号设备之间的通讯是确保生产流程顺畅、高效运行的关键。本文详细介绍了安川MP3300运动控制器与西门子1200系列PLC进行ModbusTCP通讯的具体方法。 一&#xff0e;软硬件需求 1.一台安川MP3300CPU301&#xff0c;其IP地址是192.…...

react18中如何实现同步的setState来实现所见即所得的效果

在react项目中&#xff0c;实现添加列表项&#xff0c;最后一项自动显示在可视区域范围&#xff01;&#xff01; 实现效果 代码实现 import { useState, useRef } from "react"; import { flushSync } from "react-dom"; function FlushSyncRef() {con…...

深入理解MVP架构模式

引言 MVP&#xff08;Model-View-Presenter&#xff0c;模型-视图-提供者&#xff09;是一种广泛应用于软件开发中的架构模式&#xff0c;是经典MVC&#xff08;Model-View-Controller&#xff09;的变种。在传统的MVC模式中&#xff0c;Model和View之间存在直接的依赖和数据交…...

Java面试题七

一、Java中的集合框架是如何组织的&#xff1f;列举几个常用的集合类。 Java中的集合框架是一个设计用来存储和操作对象集合的统一架构。它主要由两大接口派生出来&#xff1a;Collection和Map。这两个接口及其子接口和实现类共同构成了Java集合框架的主体。 集合框架的组织结…...

linux网络编程3——http服务器的实现和性能测试

http服务器的实现 本文使用上一篇博文实现的epollreactor百万并发的服务器实现了一个使用http协议和WebSocket协议的WebServer。 完整代码请看我的github项目 1. 水平触发(Level Trigger)与边沿触发(Edge Trigger) 1.1 水平触发 水平触发是一种状态驱动机制。当文件描述符&a…...

Docker部署Kamailio,并使用LinPhone实现网络通话

前提条件 准备一个路由器&#xff0c;一个服务器&#xff0c;两个终端设备&#xff08;手机或电脑&#xff09; docker部署安装 我使用的是windows系统&#xff0c;docker desktop 先启动Docker desktop打开cmd&#xff0c;输入docker命令docker run --name kamailio --rm…...

JAVA-石头迷阵小游戏

采用企业式项目结构,接下来我将分享全部代码和结构,希望大家点点关注! 这是我的结构。首先使用IDE创建一个Module,命名stone-maze,接着把自带src下的main方法删除,接着在src下创建包,包名为com.wmuj,接着创建APP类代码如下: package com.wmuj;public class App {publ…...

鸿蒙--进度条通知

主要介绍如何使用通知能力和基础组件,实现模拟下载文件,发送通知的案例。 效果 代码结构 ├──entry/src/main/ets // 代码区 │ ├──common │ │ ├──constants │ │ │ └──CommonConstants.ets // 公共常量类 │ │ └──utils │ │ ├──Logger.ets //…...

搜维尔科技:varjo xr-4开箱测评,工业用途头显,一流视觉保真度

varjo xr-4开箱测评&#xff0c;工业用途头显&#xff0c;一流视觉保真度 搜维尔科技&#xff1a;varjo xr-4开箱测评&#xff0c;工业用途头显&#xff0c;一流视觉保真度...

mysql数据量分库分表

一、分库分表参考阈值 分库分表是解决大规模数据和高并发访问问题的常用策略。虽然没有绝对的阈值来决定何时进行分库分表&#xff0c;但以下是一些参考阈值和考虑因素&#xff0c;可以帮助你做出决策&#xff1a; 1.1 数据量阈值 单表数据行数&#xff1a;当单表的数据行数…...

Vite创建Vue3项目以及Vue3相关基础知识

1.创建Vue3项目 1.运行创建项目命令 # 使用 npm npm create vitelatest2、填写项目名称 3、选择前端框架 4、选择语法类型 5、按提示运行代码 不出意外的话&#xff0c;运行之后应该会出现 下边这个页面 6.延伸学习&#xff1a;对比webpack和vite&#xff08;这个是面试必考…...

Elasticsearch封装公共索引增删改查

什么是索引&#xff1f; 定义&#xff1a;索引是 Elasticsearch 中用于存储数据的逻辑命名空间。它由多个文档组成&#xff0c;每个文档是一个 JSON 格式的结构化数据对应关系&#xff1a;在关系数据库中&#xff0c;索引类似于表&#xff1b;而在 Elasticsearch 中&#xff0…...

Python异常检测:Isolation Forest与局部异常因子(LOF)详解

这里写目录标题 Python异常检测&#xff1a;Isolation Forest与局部异常因子&#xff08;LOF&#xff09;详解引言一、异常检测的基本原理1.1 什么是异常检测&#xff1f;1.2 异常检测的应用场景 二、Isolation Forest2.1 Isolation Forest的原理2.1.1 算法步骤 2.2 Python实现…...

Git的原理和使用(二)

1. git的版本回退 之前我们也提到过&#xff0c;Git 能够管理⽂件的历史版本&#xff0c;这也是版本控制器重要的能⼒。如果有⼀天你发现 之前前的⼯作做的出现了很⼤的问题&#xff0c;需要在某个特定的历史版本重新开始&#xff0c;这个时候&#xff0c;就需要版本 回退的功能…...

docker 发布镜像

如果要推广自己的软件&#xff0c;势必要自己制作 image 文件。 1 制作自己的 Docker 容器 基于 centos 镜像构建自己的 centos 镜像&#xff0c;可以在 centos 镜像基础上&#xff0c;安装相关的软件&#xff0c;之后进行构建新的镜像。 1.1 dockerfile 文件编写 首先&…...

投了15亿美元,芯片创新公司Ampere为何成了Oracle真爱?

【科技明说 &#xff5c; 科技热点关注】 一个数据库软件公司却想要操控一家芯片厂商&#xff0c;这样的想法不错。也真大胆。 目前&#xff0c;全球数据库巨头甲骨文Oracle已经持有Ampere Computing LLC 29%的股份&#xff0c;并有可能通过未来的投资选择权获得对这家芯片制造…...

vue 报告标题时间来自 elementUI的 el-date-picker 有开始时间和结束时间

要在Vue中使用 Element UI 的 el-date-picker 来选择开始时间和结束时间&#xff0c;并将其展示在报告中&#xff0c;以下是详细的实现步骤。 实现思路&#xff1a; 使用 Element UI 的 el-date-picker 组件&#xff0c;让用户选择时间范围&#xff08;开始时间和结束时间&am…...

简单几何问题的通解

来&#xff0c;这道题怎么做&#xff1f;边长为2的正方形内&#xff0c;2个扇形的交集面积是多少&#xff1f;这道题一定要画辅助线&#xff0c;因为要用到两个扇形的交点&#xff0c;如果不画辅助线&#xff0c;这个交点相关的4个子图一个都无法求出面积&#xff0c;只能求出子…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...