如何将变量从一个Express路由传递到另一个路由?
解决方案
首先你得先明白一个基础逻辑:后端的每个路由请求都是独立的,用户每次调用placeOrder接口生成的currentPrice,默认只存在本次请求的上下文里,请求返回给前端之后这个变量就被销毁了,match接口是另一个独立的请求,自然没法直接拿到另一个请求里的变量。
下面给你3种不同场景的实现方法,从简单到常用:
方法1:前端传值(最适合新手快速实现)
这个方法不需要改太多后端逻辑,只需要调整前端的调用顺序就行:
- 前端先调用
placeOrder接口,拿到接口返回的currentPrice值 - 前端调用
match接口的时候,把currentPrice加到POST请求的body参数里一起传给后端 - 后端
match路由里直接从请求体取就可以了,示例代码:
//Match orders const match = async(req, res) => { // 直接从请求体拿前端传过来的currentPrice const { orderType, orderTimeFrameInput, tradeAmount, symbolSearch, kofTimeInput, currentPrice } = req.body console.log(req.body.symbolSearch) const orders = await knex("orderbook_table") .where({ order_type: "Call" }) .where({ market: symbolSearch }) .select() console.log(orders) };
注意:这个方法的缺点是用户可以篡改前端传的价格,适合不需要高安全性的测试场景用
方法2:后端Session存储(适合单用户私有数据,防止篡改)
如果不想让前端接触价格数据,防止篡改,可以用session把价格存在后端,和用户绑定:
- 先安装express-session依赖:
npm install express-session,然后在你的项目入口文件(一般是app.js/index.js)里配置session:
const session = require('express-session') app.use(session({ secret: '随便写一串字符当密钥就行', resave: false, saveUninitialized: true, cookie: { secure: false } // 开发环境设false,生产环境用https再改true }))
- 修改
placeOrder路由,把价格存在用户的session里:
const placeOrder = (req, res) => { var symbol = req.query.symbolID.split(" - ")[0].toUpperCase() console.log(symbol) finnhubClient.quote(symbol, (error, data, response) => { const currentPrice = data.c console.log(currentPrice) // 把价格存到当前用户的session里,还可以按标的存避免混淆 req.session.currentPrice = currentPrice res.send({ currentPrice }) }); };
- 直接在
match路由里取session里的价格就行:
const match = async(req, res) => { // 从当前用户的session取价格 const currentPrice = req.session.currentPrice const { orderType, orderTimeFrameInput, tradeAmount, symbolSearch, kofTimeInput } = req.body // 后面的原有逻辑不变 };
方法3:全局缓存存储(适合所有用户共用的公共价格)
如果这个标的的价格是所有用户共用的,不需要按用户区分,可以存在全局缓存里:
- 先在全局位置定义一个缓存对象,用来存不同标的的价格和过期时间:
// 放在路由文件最上面就行,key是标的代码,value是{price: 价格, expire: 过期时间戳} const priceCache = {} // 价格有效期,比如设30秒,避免缓存太旧 const PRICE_EXPIRE_TIME = 30 * 1000
- 修改
placeOrder路由,把价格写入缓存:
const placeOrder = (req, res) => { var symbol = req.query.symbolID.split(" - ")[0].toUpperCase() console.log(symbol) finnhubClient.quote(symbol, (error, data, response) => { const currentPrice = data.c console.log(currentPrice) // 写入缓存 priceCache[symbol] = { price: currentPrice, expire: Date.now() + PRICE_EXPIRE_TIME } res.send({ currentPrice }) }); };
- 在
match路由里根据标的代码取缓存里的价格:
const match = async(req, res) => { const { orderType, orderTimeFrameInput, tradeAmount, symbolSearch, kofTimeInput } = req.body // 先取缓存 const cacheItem = priceCache[symbolSearch] let currentPrice if (cacheItem && cacheItem.expire > Date.now()) { // 缓存没过期直接用 currentPrice = cacheItem.price } else { // 缓存过期了可以在这里重新调用finnhub接口拿最新价格,或者返回错误提示 } // 后面的原有逻辑不变 };
注意:这个方法存在内存里,服务器重启缓存就会清空,生产环境可以换用Redis做持久化缓存
内容的提问来源于stack exchange,提问作者calin125
相关产品推荐
相关产品推荐

