React应用单JS文件多实例运行时用户身份数据冲突问题求解
问题根因
- 浏览器同域名下的Cookie、LocalStorage是所有标签页共享的,你在第二个标签页登录消防账号时,新的登录凭证(token/sessionid等)会覆盖掉之前存储的警局账号凭证,所有同站点标签页向后端发起请求时都会携带新的凭证,后端自然返回消防部门的身份标识。
- 你当前的
fetchType方法只在组件首次挂载时触发1次,切回标签页时不会重新拉取最新的身份信息,就算后续要更新也没有触发时机。
解决方案
场景1:不需要多账号同时登录,仅需切回标签页时显示当前最新的身份信息
只需要增加页面可见性监听,切回标签页时自动重新拉取用户类型即可,修改后的组件代码如下:
import React,{useState,useEffect} from 'react' import {Link} from 'react-router-dom' import './LoginSt.css' import NavB from './Nav'; import { useHistory } from "react-router-dom" import {storage} from './Connection' import { TableCell, TableRow } from 'semantic-ui-react'; const Hello = () => { const [Type, setType] = useState(' '); let history = useHistory() useEffect(() => { // 首次挂载拉取 fetchType() // 监听页面可见性变化,切回页面时重新拉取 const handleVisibilityChange = () => { if (!document.hidden) { fetchType() } } document.addEventListener('visibilitychange', handleVisibilityChange) // 组件卸载时移除监听 return () => document.removeEventListener('visibilitychange', handleVisibilityChange) }, []); function handleclick(){ history.push("/VideoStreaming") } function fetches(){ fetch("http://localhost:5000/getEmployeeList") } function fetchType(){ fetch('http://127.0.0.1:5000/getType').then(res => res.json()).then(data => { setType(data.type); console.log(data.type); }); } return ( <div> <NavB /> <div className="cunt back"> <h2 className="whitecol heading">{Type}</h2> <button className="butt2" onClick={handleclick}>See Live Stream</button> <Link to="/oldVids"> <button className="butt3" onClick={fetches}>See Old Records</button> </Link> </div> </div> ) } export default Hello;
场景2:需要多标签页同时登录不同账号,实现完全独立的多实例运行
需要修改登录态存储逻辑,放弃使用全局共享的Cookie/LocalStorage存储凭证,改用sessionStorage存储登录凭证:
- 登录成功后把后端返回的token/sessionid存在
sessionStorage中,sessionStorage是每个标签页独立隔离的,不同标签页的存储内容不会互相覆盖 - 所有向后端发起的请求,都手动从当前标签页的
sessionStorage中取出凭证,放在请求头中携带,不要依赖浏览器自动带Cookie - 后端调整为从请求头中读取凭证校验身份,而不是从Cookie中读取
调整后不同标签页的登录凭证完全独立,就算同时登录不同账号,互相也不会干扰。
内容的提问来源于stack exchange,提问作者wasay khan
相关产品推荐
相关产品推荐

