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

服务端Session购物车正常,客户端Axios请求时Session反复重建求助

问题解决:Axios客户端中Session不断重建导致购物车异常

核心问题分析

问题本质出在两个层面:一是客户端请求未携带Session标识,导致服务端每次都创建新Session;二是Cart类的商品添加逻辑存在错误,无法正确累加已有商品数量。


修复步骤

跨域场景下Axios默认不会携带Cookie,需开启withCredentials配置:

// 若你的Service是Axios实例,添加以下配置
const Service = axios.create({
  withCredentials: true, // 关键:允许请求携带Cookie
  // 其他原有配置...
});

// Vue项目也可全局设置
axios.defaults.withCredentials = true;

2. 修正Session配置的SameSite属性

原配置中sameSite: true为旧写法,现代浏览器需明确取值,跨域场景建议设为'none'(需配合secure: true,仅HTTPS环境有效),同域场景用'lax':

app.use(session({
    secret: "hideSession",
    resave: false, // 禁用不必要的Session重复保存
    saveUninitialized: false, // 未初始化的Session不保存,减少资源占用
    cookie: {
        sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
        httpOnly: true, // 建议开启,提升Cookie安全性
        secure: process.env.NODE_ENV === 'production', // HTTPS环境下启用
        maxAge: 24 * 60 * 60 * 1000 // 可选:设置Cookie有效期,避免浏览器关闭即失效
    }
}));

3. 修复Cart类的商品累加逻辑

原addDrink方法会每次重置products对象,完全无法保留已有商品,修改如下:

module.exports = function Cart(oldCart) {
    this.products = oldCart.products || {};
    this.totalQty = oldCart.totalQty || 0;
    this.totalPrice = oldCart.totalPrice || 0.00;

    this.addDrink = function(item) {
        // 用商品名称作为唯一标识,避免重复添加时覆盖
        const itemKey = item.name;
        let storeItem = this.products[itemKey];

        if (!storeItem) {
            // 商品不存在,初始化条目
            storeItem = this.products[itemKey] = {
                item: item,
                currentQty: 1,
                price: parseFloat(item.price)
            };
            this.totalQty = 1;
            this.totalPrice = parseFloat(item.price);
        } else {
            // 商品已存在,累加数量和价格
            storeItem.currentQty++;
            storeItem.price = parseFloat(storeItem.item.price * storeItem.currentQty);
            this.totalQty++;
            this.totalPrice += parseFloat(storeItem.item.price);
        }
    }
}

4. 优化add_to_cart路由逻辑

原路由查询所有商品再筛选效率极低,直接根据name查询单条即可:

app.post("/add_to_cart/:name", async (req, res) => {
    let db = await connect();
    // 直接查询指定名称的商品,无需遍历全部数据
    const singleDrink = await db.collection("products").findOne({ name: req.params.name });
    
    if (!singleDrink) {
        return res.status(404).send({ error: "商品不存在" });
    }

    let cart = !req.session.cart ? new Cart({}) : new Cart(req.session.cart);
    cart.addDrink(singleDrink);
    req.session.cart = cart; // 确保更新后的购物车存入Session
    
    console.log(req.session.cart, req.session.cookie);
    res.send(cart);
});

验证要点

  • 打开浏览器开发者工具的Application > Cookies,确认是否存在Session ID Cookie,且每次请求的Request Headers中包含Cookie字段。
  • 查看服务端控制台打印的req.sessionID,若每次请求ID一致,说明Session已正常复用。

内容的提问来源于stack exchange,提问作者Jan Tuđan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:24:25