Node.js中如何使用POST方法内局部变量并实现跨请求共享
现有代码与报错
已引入的依赖模块
const mysql = require('mysql'); const express = require('express'); const session = require('express-session'); const path = require('path'); const bodyParser = require('body-parser'); const { dirname } = require('path'); const { request } = require('http'); const { response } = require('express'); const urlencoded = require('body-parser/lib/types/urlencoded'); const res = require('express/lib/response'); const app = express(); const port = 3000;
注:上述依赖中request、response、urlencoded、res均未在后续逻辑中使用,可以直接删除,避免冗余引入。
原有POST登录接口逻辑
app.post('/src/login.html' ,function(req , res){ var prn = req.body.prn; var password = req.body.password; connection.query('SELECT * FROM userinfo WHERE prn=? AND password=?',[prn , password],function(error, results, fields){ if (error) throw error; if(results.length > 0){ res.redirect('/src/dashboard-student'); }else{ res.redirect('/src/login.html'); } }); }); var PRN = prn; console.log(PRN);
运行报错信息
var PRN = prn;
^
ReferenceError: prn is not defined
at Object. (C:\Users\Niranjan\Desktop\SY CSE\Seminar-II\SIS\Project\app.js:115:11)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
at internal/main/run_main_module.js:17:47
报错原因
prn是定义在POST路由回调函数内的局部变量,受JavaScript函数作用域限制,在函数作用域外无法直接访问,因此触发引用错误。
正确实现方案
你已经引入了express-session依赖,直接用Session存储用户维度的变量是当前场景下的最优解:Session和单个用户的会话绑定,不同用户的数据互相隔离,不会出现数据串扰,天生适合存储登录态这类跨请求的用户专属数据。
不要用全局变量存这类用户数据——全局变量是所有请求共享的,后登录的用户会覆盖前面用户存的值,会导致严重的账号串号问题。
具体实现步骤如下:
- 注册必要中间件:在所有路由定义之前,注册body-parser和express-session中间件,否则无法正常解析请求体、使用Session能力
// 解析表单格式的请求体 app.use(bodyParser.urlencoded({ extended: true })); // 配置Session app.use(session({ secret: 'replace-with-your-own-secret-str', // 自定义签名密钥,填任意复杂字符串即可 resave: false, saveUninitialized: false, cookie: { maxAge: 86400000 } // 会话有效期,单位毫秒,这里设置为1天 })); - 登录成功后写入Session:修改登录接口逻辑,校验账号密码通过后,把
prn存入当前用户的Session中app.post('/src/login.html' ,function(req , res){ const prn = req.body.prn; const password = req.body.password; connection.query('SELECT * FROM userinfo WHERE prn=? AND password=?',[prn , password],function(error, results, fields){ if (error) throw error; if(results.length > 0){ // 登录校验通过,将prn存入当前用户会话 req.session.prn = prn; res.redirect('/src/dashboard-student'); }else{ res.redirect('/src/login.html'); } }); }); - 其他请求中读取存储的值:任意后续接口中,都可以直接从
req.session上读取之前存入的prn值,还可以顺便做登录态校验app.get('/src/dashboard-student', function(req, res) { // 未登录状态直接跳回登录页 if (!req.session.prn) { return res.redirect('/src/login.html'); } // 读取当前登录用户的prn const currentUserPrn = req.session.prn; console.log('当前访问用户PRN:', currentUserPrn); // 后续业务逻辑直接使用currentUserPrn即可 })
内容的提问来源于stack exchange,提问作者Shridhar

