Nodejs JSON.stringify() 报错粘出代码, 谢谢。

Nodejs JSON.stringify() 报错粘出代码, 谢谢。

if(req.session.curruser){ console.log(req.session.curruser); // { username: ‘mrlog2’, groupid: 1, groupname: ‘杭州某某公司’ } res.locals.curruser = req.session.curruser; //这个出错。提示如下。 };

/Users/rmbp-mrlong/code/node.js/wechatdeve/src/node_modules/express-session/session/memory.js:80 self.sessions[sid] = JSON.stringify(sess);

TypeError: Converting circular structure to JSON at Object.stringify (native) at Object._onImmediate (/Users/rmbp-mrlong/code/node.js/wechatdeve/src/node_modules/express-session/session/memory.js:80:31) at processImmediate [as _immediateCallback] (timers.js:330:15)


5 回复

根据你提供的错误信息,问题在于 req.session.curruser 对象中存在循环引用(circular structure),而 JSON.stringify() 方法无法处理这种情况。当对象中有循环引用时,JSON.stringify() 会抛出一个 TypeError

示例代码及解释

假设我们有以下代码片段:

const express = require('express');
const session = require('express-session');

const app = express();

app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true,
}));

app.get('/', (req, res) => {
    req.session.curruser = {
        username: 'mrlog2',
        groupid: 1,
        groupname: '杭州某某公司',
        // 这里添加一个循环引用
        reference: req.session
    };

    console.log(req.session.curruser);
    res.locals.curruser = req.session.curruser;
    res.send('Session set successfully');
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

在这个例子中,req.session.curruser 包含了一个指向 req.session 的引用,从而形成了循环引用。当你尝试将这个对象转换为 JSON 字符串时,JSON.stringify() 将会报错。

解决方案

要解决这个问题,你可以使用第三方库如 flatted 或者自己编写一个函数来处理循环引用。以下是一个简单的示例:

使用 flatted

npm install flatted

然后修改你的代码:

const JSON = require('flatted/json');

// ...

app.get('/', (req, res) => {
    req.session.curruser = {
        username: 'mrlog2',
        groupid: 1,
        groupname: '杭州某某公司',
        reference: req.session
    };

    console.log(req.session.curruser);
    res.locals.curruser = JSON.stringify(req.session.curruser);
    res.send('Session set successfully');
});

自定义函数

如果你不想安装额外的库,可以编写一个自定义函数来处理循环引用:

function safeStringify(obj, indent = 2) {
    const seen = new WeakSet();
    return JSON.stringify(obj, (key, value) => {
        if (typeof value === 'object' && value !== null) {
            if (seen.has(value)) {
                return;
            }
            seen.add(value);
        }
        return value;
    }, indent);
}

// ...

app.get('/', (req, res) => {
    req.session.curruser = {
        username: 'mrlog2',
        groupid: 1,
        groupname: '杭州某某公司',
        reference: req.session
    };

    console.log(req.session.curruser);
    res.locals.curruser = safeStringify(req.session.curruser);
    res.send('Session set successfully');
});

通过这种方式,你可以避免 JSON.stringify() 在遇到循环引用时抛出错误。


JSON里对象’指针’转圈了。

在前面加上 console.log(req.session) 看看 req.session 里面的数据都是什么样的

req.session 就一个数据 curruser

在Node.js中使用JSON.stringify()方法时,如果对象包含循环引用(circular references),就会抛出TypeError: Converting circular structure to JSON错误。在你的例子中,req.session.curruser对象可能包含了循环引用。

示例代码及解决方案

假设你的代码类似于这样:

if(req.session.curruser){
    console.log(req.session.curruser);  // { username: 'mrlog2', groupid: 1, groupname: '杭州某某公司' }
    res.locals.curruser = req.session.curruser;  // 这里出错
}

解决方案1:使用第三方库 circular-json

你可以使用第三方库如 circular-json 来处理循环引用问题。

安装 circular-json 库:

npm install circular-json --save

修改代码:

const CircularJSON = require('circular-json');

if(req.session.curruser){
    console.log(req.session.curruser);
    res.locals.curruser = CircularJSON.stringify(req.session.curruser);
}

解决方案2:手动移除循环引用

另一种方法是手动移除循环引用部分,这通常需要了解具体的对象结构。

例如,你可以创建一个不包含循环引用的新对象:

if(req.session.curruser){
    const safeUser = {
        username: req.session.curruser.username,
        groupid: req.session.curruser.groupid,
        groupname: req.session.curruser.groupname
    };
    console.log(safeUser);
    res.locals.curruser = safeUser;
}

总结

通过使用第三方库或手动创建不含循环引用的对象,可以有效解决 TypeError: Converting circular structure to JSON 错误。选择哪种方法取决于具体场景和需求。

回到顶部