NodeJS express-session路由间会话变量无法持久化问题排查
问题:Express Session变量无法在路由间持久化
我正尝试设置可在路由间持久化的session变量,但未能成功。发送POST请求时session变量能正常更新,但通过Postman访问另一个GET路由时,该变量为空。以下是我的代码:
const express = require('express') const session = require('express-session') const bodyParser = require('body-parser') const app = express() app.use(session({ secret: 'test one', resave: false, saveUninitialized: true, name: "mycookiesession", cookie: { secure: false } })) let mySession app.use(function (req, res, next) { mySession = req.session mySession.basket = [] next() }) app.get('/basket', function (req, res) { console.log(mySession.basket) res.send(mySession.basket) }) app.post('/basket/add', function (req, res) { mySession.basket = [0, 1, 2] console.log(mySession.basket) res.send('null') res.status(201).end() }) app.listen(3000, function () { console.log('Example app listening') })
请问我哪里出错了?我需要在GET:/basket路由中获取POST:/basket/add添加到basket的变量值。
解决方案
你的代码存在两个核心问题,直接导致session无法持久化:
全局变量
mySession的误用
Express是多请求并发模型,全局变量会被所有请求共享覆盖。当新请求进来时,mySession会被更新为当前请求的session实例,之前请求存储的session数据会直接丢失。正确做法是直接使用每个请求自带的req.session,不要用全局变量存储。中间件强制重置
basket为空数组
你在全局中间件里写了mySession.basket = [],这意味着每一次请求(不管是GET还是POST)进来,都会把basket强制重置为空数组。哪怕POST请求刚把basket设为[0,1,2],下一次GET请求触发中间件时,basket又会被清空。
修改后的代码如下:
const express = require('express') const session = require('express-session') const bodyParser = require('body-parser') const app = express() // 解析POST请求体,否则无法获取请求参数 app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: true })) app.use(session({ secret: 'test one', resave: false, saveUninitialized: true, name: "mycookiesession", cookie: { secure: false } })) // 仅当basket不存在时初始化,避免每次请求重置 app.use(function (req, res, next) { if (!req.session.basket) { req.session.basket = [] } next() }) app.get('/basket', function (req, res) { console.log(req.session.basket) res.send(req.session.basket) }) app.post('/basket/add', function (req, res) { req.session.basket = [0, 1, 2] console.log(req.session.basket) // 避免重复结束响应,合并状态码与响应内容 res.status(201).send('添加成功') }) app.listen(3000, function () { console.log('Example app listening') })
额外注意:测试时要在Postman中开启保存Cookies选项,session是通过Cookie标识用户身份的,如果Postman不保存Cookie,每次请求都会被视为新用户,session自然无法共享。
内容的提问来源于stack exchange,提问作者soundcake
相关产品推荐
相关产品推荐

