React应用部署Ubuntu服务器(Nginx)后,刷新时localStorage丢失JWT求助
兄弟,我之前也踩过几乎一模一样的坑!结合你描述的情况——本地刷新正常、Nginx生产环境下刷新就登出,但控制台还能打出Bearer Token,大概率是这几个方向的问题,咱们一步步捋:
1. Nginx路由重写配置缺失(最常见的单页应用部署坑)
React是单页应用,正常跳转是前端路由接管,但刷新页面时浏览器会直接向Nginx请求当前路径(比如/user/profile)。如果Nginx没配置正确的重写规则,会直接返回404,这时候你的应用会被迫重新初始化,哪怕localStorage里有Token,也可能因为应用重启时的状态同步逻辑出错,导致登录状态丢失。
解决方案:在Nginx的站点配置里,给根路径加上try_files规则,让所有非静态资源请求都指向index.html:
location / { try_files $uri $uri/ /index.html; }
先检查刷新时Network面板的请求,有没有404返回,有的话先把这个配置加上重启Nginx试试。
2. 登录状态初始化时机或逻辑问题
你说控制台能打印出Token,说明localStorage读取是成功的,但可能状态管理的同步出了问题:
- 比如你用Redux、Zustand这类状态库,有没有在应用启动时(比如store初始化、根组件的
useEffect)正确从localStorage读取Token并同步到状态中? - 会不会生产环境下因为代码压缩、严格模式(不过本地也会触发严格模式)导致初始化逻辑没执行?
- 排查下:刷新后,看看状态管理里的登录状态是不是真的被设置了,还是只有console打印了Token但状态是空的?
3. Token有效性或环境不匹配问题
虽然能打印Token,但也有可能是Token本身的问题:
- 把控制台的Token拿到jwt.io解析,看看
exp过期时间是不是刚好在刷新时到期了?本地环境的Token可能是测试用的有效期长,生产环境的Token时效更短? - 检查Token的
iss(签发者)、aud(受众)是不是和生产环境的后端配置一致?本地和生产的后端域名不同,可能导致后端验证Token时不通过,返回未授权,前端就登出了。 - 另外,如果生产环境是HTTPS,看看Nginx有没有配置
Content-Security-Policy这类安全头限制了localStorage?不过你能读到Token,这个概率不大,但可以检查下响应头里的CSP设置。
4. Nginx静态资源缓存导致旧代码加载
如果你的React打包文件加了哈希后缀(默认会加),但Nginx缓存配置没跟上,浏览器可能加载了旧的静态文件,而旧代码里的登录状态逻辑有问题:
- 检查Nginx的静态资源缓存配置,确保带哈希的文件可以长期缓存,不带哈希的
index.html不缓存:
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 1y; add_header Cache-Control "public, immutable"; } location = /index.html { expires -1; add_header Cache-Control "no-cache, no-store, must-revalidate"; }
可以先强制清除浏览器缓存(Ctrl+Shift+R)刷新试试,如果正常了,就是缓存的锅。
先从Nginx的路由配置开始排查,这个是单页应用部署最容易忽略的点,大概率能解决你的问题!
内容的提问来源于stack exchange,提问作者jhonathan myers
相关产品推荐
相关产品推荐

