You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 16:48:21