编程导航Cookie话题讨论

Cookie

2 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡

Nginx 跨域 + 无法设置 Cookie 解决办法 + 使用域名访问

首先 F12 看 login 接口对应的网络请求有没有 ⚠️,如果有那是后端的问题,如果没有那是前端的问题 ## 前端问题 前端没有携带 cookie 导致后端识别不到 1) 前端 axios 是否开启了 withCredentials=true 2) 在 OpenAPI 的那边配置项,设置下 withCrendential <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/gW4aFU1njcXhhvtN.webp" alt="img" width="100%" /> ## 后端问题 确认环境 1)确保后端跨域注解或者配置要删除,鱼皮项目一般是 config/CrosConfig.java > 跨域方式只有一种就可以(一般是后端配置或者 Nginx),咱们这里就使用 Nginx 解决跨域 2)如果使用国内服务器,想要使用域名必须要`备案` 3)YML 配置 ```yml server: servlet: session: cookie: domain: 域名或者IP ``` > http 环境就不要使用 secure 和samesite ### 使用宝塔跨域 #### Easy 跨域配置 在宝塔前端配置文件 **非常重要,一定确保「前端请求地址」和「前端运行地址」地址一致!!!** **这种方式需要确保** **1、后端没有配置跨域, 一般是 config/CrosConfig.java (具体内容下面的图片)** **2、前端请求的地址是,前端运行的 IP 或者前端的域名** **比如下面这几种情况** **1)比如前端 IP 是 123.123.123.123 那么前端请求后端的地址也是 123.123.123.123** **2)比如前端 IP 是 123.123.123.123:90 那么前端请求后端的地址也是 123.123.123.123:90** **3)比如前端域名是 leikooo.com 那么前端请求后端请求的地址也是 leikooo.com** <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/g0R8KeESvB5cNcOZ.webp" alt="image.png" width="100%" /> > 前端请求地址和前端运行地址一致 也就是前端 baseURL 请求 192.168.196.158:8000 具体参考自己运行地址 后端跨域配置 <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/21pbGbVFQ5w1QIn7.webp" alt="image.png" width="100%" /> 需要修改宝塔具体位置 <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/rhdSmndvZtGBZ6Yh.webp" alt="image.png" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/oQ38EqG7a4mdjyeR.webp" alt="image.png" width="100%" /> 如果是原生的 Nginx 下面是完整的代码,如果是宝塔的话只需要复制两个 `location` 模块到前端配置文件即可 ,**注意一定不要换顺序!** ``` server { listen 80; server_name 前端 IP 比如 126.4.3.3; root 前端路径; location /api { proxy_pass http://127.0.0.1:后端端口; proxy_set_header Host $proxy_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffering off; proxy_set_header Connection ""; } # 这个要写在下面! location / { index index.html index.htm; try_files $uri $uri/ /index.html; } } ``` --- BUG 比如,下面这种情况: <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/E6qnVzu2ALVtOTiN.webp" alt="image.png" width="100%" /> 所以会导致跨域失败! > 解决方法:前端的 baseUrl 修改成前端运行地址 #### Hard 跨域配置 1、如果之前使用的是下面这种跨域方式也要删除掉/注释! <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/eDZMvNA4CQtfbmsG.png" alt="image.png" width="590px" /> 2、这种方式是前端请求一个独立于前端和后端的端口,比如 前端 80 后端 8080 ,那么前端请求 90 端口让 90 对端口进项反向代理到后端 3、上面的 easy 方式虽然简单,但是如果后端想要使用独立的子域名的情况下就不适用了 --- <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/NJN3DmEuksQN2umo.webp" alt="image-20240914115007224" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/mqafC2zfCRO7NcYm.webp" alt="image-20240914115143570" width="100%" /> ```nginx # 后端相关的反向代理+跨域 server { # 这个监听的端口任意都行,但是要注意前端要请求这个端口 listen 90; server_name 前端 IP 比如 126.4.3.3; location / { # 禁止非 GET|POST|HEAD|OPTIONS|PUT|PATCH|DELET 的请求 if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444; } set $origin $http_origin; # 重点!比如: # $origin !~ '^http?://leikooo\.com$ # $origin !~ '^http?://127.0.0.1$ if ($origin !~ '^http?://服务器IP$') { set $origin 'http://服务器IP'; } if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' "$origin" always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header Access-Control-Max-Age 1728000; add_header Content-Type 'text/plain charset=UTF-8'; add_header Content-Length 0; return 204; } if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') { add_header Access-Control-Allow-Origin "$origin" always; add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always; add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always; add_header Access-Control-Allow-Credentials true always; } # 反向代理到后端具体运行的端口 proxy_pass http://localhost:后端实际运行端口; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` 请求流程图 <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/pbK8y7G4dTiM88WC.webp" alt="image.png" width="100%" /> 使用域名 前端请求后端的域名,然后在 Nginx 配置跨域和反向代理,访问到真正的后端 ```nginx # 后端相关的反向代理+跨域 server { # http 默认 80 端口 https 默认 443 端口 listen 80; server_name 修改成自己的子域名; # 比如 backend.leikooo.com location / { # 禁止非 GET|POST|HEAD|OPTIONS|PUT|PATCH|DELET 的请求 if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444; } set $origin $http_origin; # 重点!比如: # $origin !~ '^http?://leikooo\.com$ # 下面配置前端域名,比如 leikooo.cn if ($origin !~ '^http?://前端域名$') { set $origin '前端域名'; } if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' "$origin" always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header Access-Control-Max-Age 1728000; add_header Content-Type 'text/plain charset=UTF-8'; add_header Content-Length 0; return 204; } if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') { add_header Access-Control-Allow-Origin "$origin" always; add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always; add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always; add_header Access-Control-Allow-Credentials true always; } # 反向代理到后端具体运行的端口 # 如果后端开启了 https 不要忘记请求协议变成 https proxy_pass http://localhost:后端实际运行端口; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` **注意**: 1)前端请求 `90` (上面 server 模块下 listen 的端口)而不是直接请求后端实际运行端口 <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/nIMHYqIdfUjDuCxz.webp" alt="image.png" width="100%" /> 2) 直接请求后端端口,那么 Nginx 就失去了存在的意义! 3)宝塔 + 服务器放行 `90` 端口,这个要注意!!(具体看自己写的是哪个端口) 4)完成 添加 nginx 配置 + 放行端口 正常就没什么问题了! 5)后端配置文件如果写了 samesite 或者 sercure 属性要删除掉! <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/OxyP89FpOL9rkP9n.webp" alt="image.png" width="100%" /> 6)后端写了跨域配置要 删除/注释 一般是 @CrossOrigin 或者 CrosConfig ### 使用原生 Nginx 跨域 经过实际测试,用 nginx 跨域就可以解决 ```nginx user root; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; access_log logs/access.log; sendfile on; keepalive_timeout 65; #gzip on; # 前端配置不是重点 server { listen 80; server_name 前端 IP 比如 126.4.3.3 ; root /root/app/dist; # 访问默写前端页面 404 就是没加下面这行的原因 try_files $uri $uri/ /index.html; location / { index index.html index.htm; } } # 后端相关的反向代理+跨域 server { # 这个监听的端口任意都行,但是要注意前端要请求这个端口 listen 90; server_name 前端 IP 比如 126.4.3.3; location / { # 禁止非 GET|POST|HEAD|OPTIONS|PUT|PATCH|DELET 的请求 if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444; } set $origin $http_origin; # 重点!比如: # $origin !~ '^http?://leikooo\.com$ # $origin !~ '^http?://127.0.0.1$ if ($origin !~ '^http?://服务器IP$') { set $origin 'http://服务器IP'; } if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' "$origin" always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header Access-Control-Max-Age 1728000; add_header Content-Type 'text/plain charset=UTF-8'; add_header Content-Length 0; return 204; } if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') { add_header Access-Control-Allow-Origin "$origin" always; add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always; add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always; add_header Access-Control-Allow-Credentials true always; } # 反向代理到后端具体运行的端口 proxy_pass http://localhost:后端实际运行端口; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } } ``` 使用域名 要注意一点,使用了下面的配置,就不需要再更改宝塔前端项目的 Nginx 配置(不需要再添加任何配置,比如 proxy_pass 之类的),当然也不用单独再配置一个前端项目 类似这种 <img src="https://pic.code-nav.cn/post_picture/1608460212774109186/KQuO0VVOVab2dchO.webp" alt="image.png" width="100%" /> ```nginx user root; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; access_log logs/access.log; sendfile on; keepalive_timeout 65; #gzip on; # 前端配置不是重点 server { listen 80; # 修改成前端的域名 server_name leikooo.cn; root /root/app/dist; # 访问默写前端页面 404 就是没加下面这行的原因 try_files $uri $uri/ /index.html; location / { index index.html index.htm; } } # 后端相关的反向代理+跨域 server { # 比如我们配置 backend.leikooo.cn 这个是后端域名 # http 默认 80 端口 https 默认 443 端口 listen 80; server_name 修改成自己的二级域名; # 我设置的一般就是 backend.leikooo.cn location / { # 禁止非 GET|POST|HEAD|OPTIONS|PUT|PATCH|DELET 的请求 if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444; } set $origin $http_origin; # 重点!比如: # $origin !~ '^http?://leikooo\.com$ # 下面配置前端域名,比如 leikooo、.cn if ($origin !~ '^http?://前端域名$') { set $origin '前端域名'; } if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' "$origin" always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header Access-Control-Max-Age 1728000; add_header Content-Type 'text/plain charset=UTF-8'; add_header Content-Length 0; return 204; } if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') { add_header Access-Control-Allow-Origin "$origin" always; add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always; add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always; add_header Access-Control-Allow-Credentials true always; } # 反向代理到后端具体运行的端口 # 如果后端开启了 https 不要忘记请求协议变成 https proxy_pass http://localhost:后端实际运行端口; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } } ``` **注意**: 1)前端请求 `9090` 而不是直接请求后端实际运行端口 2)服务器放行 `9090` 端口,这个要注意!!(具体看自己写的是哪个端口) ### Nginx 解决跨域原理 1. 跨域问题的原因 跨域问题是由浏览器的 **同源策略(Same-Origin Policy)** 引起的。同源策略要求: 协议、域名、端口都必须一致。 如果前端和后端运行在不同的域名、IP 或端口上,例如: 前端地址为 http://126.4.3.3 后端地址为 http://126.4.3.3:8080 浏览器会认为它们是不同源,因此会阻止请求,这是跨域问题的本质。 2. 如何解决跨域问题的配置逻辑 Nginx 配置中,location /api 是关键: ``` location /api { proxy_pass http://127.0.0.1:后端端口; proxy_set_header Host $proxy_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffering off; proxy_set_header Connection ""; } ``` 这里通过 Nginx 的反向代理机制: 将前端通过 /api 路径发起的请求转发到后端(即 http://127.0.0.1:后端端口 )。 对于前端来说,请求的域名和端口仍然是 http://126.4.3.3 ,从浏览器的角度看,请求是同源的。 ### 使用 HTTPS 实际测试使用域名 + HTTPS 也可以解决,解决无法设置 cookie 的问题 教程:https://www.codefather.cn/post/1831983737277050881 ## BUG 1、前端使用域名,但是前端后端使用 ip ,导致 session 设置不上 解决:前后端统一,要用域名都用域名、IP 都用 IP 2、还是不行? 1)检查端口是否放行!!! 2)前端请求的端口是否是 Nginx listen 的端口,不要直接请求实际端口 !!!

浅谈Cookie和Session

<html> <head></head> <body> <div class="content ql-editor"> <p><br></p> <h1><strong style="color: rgb(51, 51, 51);">浅谈session和cookie</strong></h1> <p><br></p> <p>最近写了好多次登录注册的业务接口,那不免会听到session、cookie等概念。那么他们是什么呢?之间的关系?有啥作用呢?我这次终于好好捋清楚他们的关系了,这次做一次学习总结。</p> <p><br></p> <h2><strong style="color: rgb(51, 51, 51);">背景</strong></h2> <p>先讨论Session和Cookie,我们先了解其诞生的背景,<strong>毕竟需求推动技术的</strong>!</p> <p>基于以前的互联网的网络协议的请求是HTTP(无状态的网络请求协议),意味着每个单独的请求之间是<strong>相互独立、互不相关</strong>的,服务器在处理一个请求后并不会保存任何关于客户端状态的信息。这样带来的弊端就是服务端无法判断客户端发来的请求是哪个用户发起的,因此我们就需要对<strong>状态保持进行额外处理</strong>,这就诞生了Cookie和Session。</p> <p><br></p> <h2><strong style="color: rgb(51, 51, 51);">Cookie</strong></h2> <h3><strong style="color: rgb(51, 51, 51);">概念</strong></h3> <p>Cookie(HTTP Cookie)是由服务器(服务端)发送到用户浏览器(客户端)并保存在用户本地计算机上的<strong>小型文本文件</strong>(可持久化)。Cookie 用于存储特定网站的用户信息(状态保持),以便在用户访问同一网站时可以检索和使用这些信息。</p> <p><br></p> <h3><strong style="color: rgb(51, 51, 51);">应用场景</strong></h3> <p>概念似乎晦涩难懂,以一些应用场景举例,就可能体察到Cookie的存在啦</p> <ol> <li data-list="ordered"><span class="ql-ui"></span>用户登录,存储账号密码</li> </ol> <p>这个就必须是<strong>首次登录成功后</strong>,浏览器会提示用户是否要保存账号信息,这个本质就是通过Cookie进行用户信息的存储,下次就可以直接免登陆操作了。</p> <blockquote> <div class="blockquote-item"> PS:免登陆不是说不用通过数据库查询,而是下次登录的信息从Cookie中取出。 </div> </blockquote> <p><span class="ql-font-monospace"> </span><img src="https://pic.code-nav.cn/planet_post_image/1620599227736473602/3uhlwmdp.jpeg"></p> <p>2. 会话管理</p> <p>用于检测用户是否在网站登录后有进行连续操作(访问网站资源),否则超过过期时间,则会消失,即用户就得重新校验身份。例如:哔站登录后不作任何操作,30天过需要重新登录。</p> <p>3. 个性化体验</p> <p>这种存储个人偏好配置,采用的方案之一就有是Cookie进行的。个人偏好配置比如:暗黑模式,页面布局、语言选择等等。</p> <p><br></p> <h3><strong style="color: rgb(51, 51, 51);">作用</strong></h3> <p>通过上面的介绍,Cookie的作用也应该已经呼之欲出了!这里还是总结一下~</p> <ol> <li data-list="bullet"><span class="ql-ui"></span>服务器识别用户,保持用户在跳转页面时会话状态的一致性。</li> <li data-list="bullet"><span class="ql-ui"></span>实现免登陆,自动进行身份验证</li> <li data-list="bullet"><span class="ql-ui"></span>保留个性化体验</li> </ol> <p><br></p> <h3><strong style="color: rgb(51, 51, 51);">存储位置</strong></h3> <p>既然Cookie是存储在本机的小型文本,那么它具体存储在哪里呢?</p> <p>答:不同的浏览器和不同的操作系统,Cookie存储本机的位置都是不同的。见下图(Chatgpt如是说)</p> <p><span class="ql-font-monospace"> </span></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1620599227736473602/n37ftjgw.jpeg"></p> <h2><strong style="color: rgb(51, 51, 51);">Session</strong></h2> <p>Session的中文名是会话,Session和Cookie可谓是“黄金搭档”,有了Cookie就一定有Session。</p> <p><br></p> <h4><strong style="color: rgb(51, 51, 51);">概念</strong></h4> <p>会话(Session)是指在用户与服务器<strong>(服务端)</strong>之间建立的一个交互周期。它允许服务器跟踪用户在一系列请求和响应之间的状态,从而实现一定程度的状态保持。意思就是我们常说的Session是存在于服务端的一个概念,用于跟踪用户的请求和响应。</p> <p>问题:</p> <ol> <li data-list="ordered"><span class="ql-ui"></span>浏览器的Cookie里面也有session,和服务端的Session的区别是什么?</li> </ol> <p>答:前者的Session又称之为<strong>会话Cookie</strong>,他是属于浏览器进程中Session,一旦关闭浏览器,会话Cookie就会被杀死,因此是<strong>不具持久化</strong>的;后者的<strong>Session</strong>是创建于服务端,他可以<strong>被持久化</strong>,可以存储多个地方,如:内存,磁盘等。</p> <p><br></p> <h4><strong style="color: rgb(51, 51, 51);">Cookie和Session的关系</strong></h4> <p>我以关系图来表示,这样显得更直观。</p> <p><span class="ql-font-monospace"> </span></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1620599227736473602/ht3vkt25.jpeg"></p> <p><br></p> <h4><strong style="color: rgb(51, 51, 51);">Session的生命周期</strong></h4> <p>这里就得要分类讨论了,浏览器的Session(会话Cookie)和服务端的Session的生命周期是不一样的。</p> <ol> <li data-list="bullet"><span class="ql-ui"></span>会话Cookie:浏览器端的 Session 存储在用户的浏览器中,通常在<strong style="font-family: inherit; font-size: inherit;font-style;font-variant-ligatures;font-variant-caps;">用户关闭浏览器时结束</strong>。这种 Session 只在用户的当前浏览器窗口或标签页内有效。当用户关闭浏览器时,浏览器通常会清除与该 Session 相关的 Cookie 数据。</li> <li data-list="bullet"><span class="ql-ui"></span>Session:服务端的 Session 存储在服务器上,其<strong style="font-family: inherit; font-size: inherit;font-style;font-variant-ligatures;font-variant-caps;">生命周期通常由服务器的配置来控制</strong>。服务端的 Session 可以在用户的多个请求之间保持状态,而不受用户关闭浏览器的影响。</li> </ol> <p>问题:</p> <ol> <li data-list="ordered"><span class="ql-ui"></span>不同用户在同一个浏览器同一个标签页发起同一个请求,sessionId相同吗?</li> </ol> <blockquote> <div class="blockquote-item"> 是相同的,但这样当前的session的value会被下一个请求的session的value覆盖。(前提是session的key是相同的) </div> </blockquote> <ol> <li data-list="ordered"><span class="ql-ui"></span>同一个浏览器不同的标签页发起同一个请求,sessionId相同吗?</li> </ol> <blockquote> <div class="blockquote-item"> 是相同的,因为依旧遵照这同一个浏览器同一个请求,其sessionId是不变的。 </div> </blockquote> <ol> <li data-list="ordered"><span class="ql-ui"></span>不同浏览器发起同一个请求,sessionId相同吗?</li> </ol> <blockquote> <div class="blockquote-item"> 是不同的,因为请求的对象都变了,sessionId肯定不同 </div> </blockquote> <p>口说无凭,我进行了实验,写了一个很简单的请求,进行了测试。</p> <div class="ql-code-block-container"> <div class="ql-code-block"> <span class="ql-token hljs-meta">@GetMapping("/test")</span> </div> <div class="ql-code-block"> <span class="ql-token hljs-keyword">public</span> <span class="ql-token hljs-keyword">void</span> <span class="ql-token hljs-title">test(HttpServletRequest request, HttpServletResponse response)</span> <span class="ql-token hljs-keyword">throws</span> IOException { </div> <div class="ql-code-block"> <span class="ql-token hljs-type">String</span> <span class="ql-token hljs-variable">id</span> <span class="ql-token hljs-operator">=</span> request.getSession().getId(); </div> <div class="ql-code-block"> response.getWriter().write(id); </div> <div class="ql-code-block"> } </div> </div> <p>Edge浏览器的SessionId:</p> <p><span class="ql-font-monospace"> </span><img src="https://pic.code-nav.cn/planet_post_image/1620599227736473602/70hahm93.jpeg"></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1620599227736473602/6nbd05zi.jpeg"></p> <p>Chrome的SessionId</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1620599227736473602/rzfvz08a.jpeg"></p> <p><span class="ql-font-monospace"> </span></p> <p>总结:总结:不管是否是同一个用户还是不同的标签,只要符合<strong>同一个浏览器同一个请求</strong>,那么的sessionId一定是相同的!</p> <p><br></p> <h2><strong style="color: rgb(51, 51, 51);">参考</strong></h2> <p><br></p> <p><a href="https://blog.csdn.net/java_faep/article/details/78082802" target="_blank" style="color: rgb(65, 131, 196);">服务器端Session、客户端Session和Cookie的区别_session在网络应用中称为会话,每个用户首次与web服务器建立连接时,就会产生一个se-CSDN博客</a></p> <p><a href="https://blog.csdn.net/samniwu/article/details/90417160" target="_blank" style="color: rgb(65, 131, 196);">java中session的用法与原理-CSDN博客</a></p> <p><a href="https://blog.csdn.net/qq_41538097/article/details/106239901" target="_blank" style="color: rgb(65, 131, 196);">session何时被创建,何时被销毁以及设置session过期时间_session对象在什么时候被创建-CSDN博客</a></p> <p><a href="https://blog.csdn.net/hanziang1996/article/details/78969044" target="_blank" style="color: rgb(65, 131, 196);">Session的生命周期和工作原理-CSDN博客</a></p> <p><a href="https://blog.csdn.net/zhujason9107/article/details/52808648" target="_blank">session什么情况下会改变_什么样的情况下会出现不同session-CSDN博客</a></p> <p><br></p> <p><br></p> </div> </body> </html>

下载 APP